using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using HslCommunication;
using HslCommunication.ModBus;
using HslCommunication.Profinet.Siemens;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Opc.Ua;
using OpcUaHelper;
using WIT.DAQ.Core.Enums;
using WIT.DAQ.Core.Extension;
using WIT.DAQ.Core.Forms;
using WIT.DAQ.Core.Helper;
using WIT.DAQ.Core.Models;
using WIT.DAQ.Core.Protocols.Socket;

namespace WIT.DAQ.Core;

/// <summary>
/// WIT.DAQ.Core通用功能类，包含大量系统常量、静态窗口、通用方法等。
/// </summary>
public class Common
{
	internal static bool Flag_Sick = false;

	/// <summary>
	/// 程序名
	/// </summary>
	public const string APPLICATION_NAME = "WIT.DAQ";

	internal static readonly string PLUGIN_FILENAME = AppDomain.CurrentDomain.BaseDirectory + "WIT.DAQ.Plugin.dll";

	/// <summary>
	/// 辅助程序进程名
	/// </summary>
	internal const string ASSISTANT_PROCESSNAME = "WIT.DAQ.Assistant";

	/// <summary>
	/// 辅助程序文件全名
	/// </summary>
	internal static readonly string ASSISTANT_FILENAME = AppDomain.CurrentDomain.BaseDirectory + "WIT.DAQ.Assistant.exe";

	/// <summary>
	/// 按钮文字描述：启动状态
	/// </summary>
	internal const string BTN_TEXT_WORKING = "停止数据采集";

	/// <summary>
	/// 按钮文字描述：停止状态
	/// </summary>
	internal const string BTN_TEXT_NOTWORKING = "启动数据采集";

	/// <summary>
	/// OPCUA协议NodeId中的分隔符
	/// </summary>
	internal const string OPCUASEPARATOR = ".";

	/// <summary>
	/// 命令窗口
	/// </summary>
	internal static CommandForm COMMAND_FORM;

	/// <summary>
	/// 实时监控窗口
	/// </summary>
	internal static MonitorForm MONITOR_FORM;

	/// <summary>
	/// 详细数据窗口
	/// </summary>
	internal static DetailForm DETAIL_FORM;

	/// <summary>
	/// 设置窗口
	/// </summary>
	internal static SettingForm SETTING_FORM;

	/// <summary>
	/// 设备管理窗口
	/// </summary>
	internal static DeviceMgrForm DEVICEMGR_FORM;

	/// <summary>
	/// 站点管理窗口
	/// </summary>
	internal static StationMgrForm STATIONMGR_FORM;

	/// <summary>
	/// 采集项管理窗口
	/// </summary>
	internal static DAQMgrForm DAQMGR_FORM;

	/// <summary>
	/// SocketServer监控窗口
	/// </summary>
	internal static SocketServerMonitorForm SOCKETSERVER_MONITOR_FORM;

	/// <summary>
	/// 日志窗口
	/// </summary>
	internal static LogViewForm LOGVIEW_FORM;

	/// <summary>
	/// 性能监控窗口
	/// </summary>
	internal static PerformanceForm PERFORMANCE_FORM;

	/// <summary>
	/// 删除日志窗口
	/// </summary>
	internal static DelLogForm DELLOG_FORM;

	/// <summary>
	/// 配置文件夹名称
	/// </summary>
	internal const string CONFIG_FOLDER_NAME = "options";

	/// <summary>
	/// 数据采集配置文件名
	/// </summary>
	internal const string CONFIG_FILE_NAME = "daq.config";

	/// <summary>
	/// 数据采集配置文件完整路径
	/// </summary>
	internal static readonly string CONFIG_FILE_FULL_PATH = AppDomain.CurrentDomain.BaseDirectory + "options\\daq.config";

	/// <summary>
	/// 程序全局设置文件名
	/// </summary>
	private const string SETTING_FILE_NAME = "daq.setting";

	/// <summary>
	/// 程序全局设置文件完整路径
	/// </summary>
	internal static readonly string SETTING_FILE_FULL_PATH = AppDomain.CurrentDomain.BaseDirectory + "options\\daq.setting";

	internal const string CUSTOMMENU_FILE_NAME = "daq.custommenu";

	internal static readonly string CUSTOMMENU_FILE_FULL_PATH = AppDomain.CurrentDomain.BaseDirectory + "options\\daq.custommenu";

	/// <summary>
	/// deadline filepath
	/// </summary>
	internal static readonly string DEADLINE_FILEPATH = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\ddl.txt";

	internal static readonly string COUNTDOWN_FILEPATH = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "\\hourscd.txt";

	/// <summary>
	/// AppData\Roaming路径
	/// </summary>
	internal static readonly string APPDATA_PATH = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

	/// <summary>
	/// 备份文件夹名称
	/// </summary>
	private const string BAK_FOLDER_NAME = "BAK";

	/// <summary>
	/// 备份文件夹路径
	/// </summary>
	internal static readonly string BAK_FOLDER_PATH = APPDATA_PATH + "\\WIT.DAQ\\BAK";

	/// <summary>
	/// 个人配置ini文件名
	/// </summary>
	private const string MY_INI_NAME = "myconfig.ini";

	/// <summary>
	/// 个人配置ini路径
	/// </summary>
	internal static readonly string MY_INI_PATH = APPDATA_PATH + "\\WIT.DAQ\\myconfig.ini";

	private static int _logSourceType;

	/// <summary>
	/// 默认连接字符串
	/// </summary>
	internal const string DefaultConnStr = "Data Source=127.0.0.1;Database=daq.log;User Id=root;Password=root;charset=utf8;pooling=true;Allow User Variables=True;SslMode=None;";

	/// <summary>
	/// Remoting通道名称
	/// </summary>
	public const string REMOTING_CHANNELNAME = "WIT_REMOTING_CHANNEL";

	/// <summary>
	/// Remoting端口
	/// </summary>
	public const int REMOTING_PORT = 10000;

	/// <summary>
	/// 按钮文字描述：Remoting启动状态
	/// </summary>
	internal const string BTN_TEXT_REMOTING = "关闭远程服务";

	/// <summary>
	/// 按钮文字描述：Remoting停止状态
	/// </summary>
	internal const string BTN_TEXT_NOTREMOTING = "开启远程服务";

	/// <summary>
	/// SocketServer端口
	/// </summary>
	public const int SOCKETSERVER_PORT = 10001;

	/// <summary>
	/// 按钮文字描述：SocketServer启动状态
	/// </summary>
	internal const string BTN_TEXT_SOCKETSERVER_WORKING = "关闭Socket服务";

	/// <summary>
	/// 按钮文字描述：SocketServer停止状态
	/// </summary>
	internal const string BTN_TEXT_SOCKETSERVER_NOTWORKING = "开启Scoket服务";

	/// <summary>
	/// OPCUA动态类缓存池（第1层key为设备Id，第2层key为NodeId ）
	/// </summary>
	internal static Dictionary<Guid, Dictionary<string, Type>> DYNAMICCLASS_POOL = new Dictionary<Guid, Dictionary<string, Type>>();

	/// <summary>
	/// 反编译得到的方法和类实例缓存池（第1层key为Namespace，第2层key为Class，第3层key为Method）
	/// </summary>
	internal static Dictionary<string, Dictionary<string, Dictionary<MethodInfo, object>>> METHOD_POOL = new Dictionary<string, Dictionary<string, Dictionary<MethodInfo, object>>>();

	private const string LOG_FILENAME = "DAQ.Log.db";

	private static readonly string LOG_FILEPATH = AppDomain.CurrentDomain.BaseDirectory + "DAQ.Log.db";

	private static readonly string LOG_CONNSTR = ((LogSourceType == 1) ? GetConnectionString(LOG_FILEPATH) : ConnStr);

	/// <summary>
	/// 对sqlite中log_process表执行写操作的线程互斥锁
	/// </summary>
	private static object LOCK_WRITE_PROCESS = new object();

	/// <summary>
	/// 对sqlite中log_processdetail表执行写操作的线程互斥锁
	/// </summary>
	private static object LOCK_WRITE_PROCESSDETAIL = new object();

	/// <summary>
	/// 是否自动开始数据采集
	/// </summary>
	/// <returns></returns>
	internal static bool AutoDAQ
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("DAQ");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoDAQ");
			return Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 程序开启后是否自动最小化
	/// </summary>
	/// <returns></returns>
	internal static bool AutoMinimized
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("AutoMinimized");
			return xmlElement != null && Convert.ToBoolean(xmlElement.InnerText);
		}
	}

	/// <summary>
	/// 自动执行任务时的超时时长(s)
	/// </summary>
	internal static int TaskTimeout
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("DAQ");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("TaskTimeout");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 是否自动开启Remoting
	/// </summary>
	/// <returns></returns>
	internal static bool AutoRemoting
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("DAQ");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoRemoting");
			return Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 是否自动开启SocketServer
	/// </summary>
	/// <returns></returns>
	internal static bool AutoSocketServer
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("DAQ");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoSocketServer");
			return Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 设备管理页面Ping设备IP的频率(ms)
	/// </summary>
	/// <returns></returns>
	internal static int PingDeviceInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("PingDeviceInterval");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 实时监控采集项的频率(ms)
	/// </summary>
	/// <returns></returns>
	internal static int MonitorInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("MonitorInterval");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 自动内存回收的频率(min)
	/// </summary>
	internal static int GCInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("GCInterval");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 判断占用内存的频率(s)
	/// </summary>
	internal static int GetMemoryInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("GetMemoryInterval");
			return (xmlElement2 != null) ? Convert.ToInt32(xmlElement2.InnerText) : 60;
		}
	}

	/// <summary>
	/// 自动备份配置文件的频率(day)
	/// </summary>
	/// <returns></returns>
	internal static int BAKInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("BAKInterval");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// OPCUA的KeepAlive频率(ms)
	/// </summary>
	/// <returns></returns>
	internal static int OPCUAKeepAliveInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("KeepAlive");
			XmlElement xmlElement3 = (XmlElement)xmlElement2.SelectSingleNode("OPCUA");
			return Convert.ToInt32(xmlElement3.InnerText);
		}
	}

	/// <summary>
	/// SocketClient的KeepAlive频率(ms)
	/// </summary>
	/// <returns></returns>
	internal static int SocketClientKeepAliveInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Interval");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("KeepAlive");
			XmlElement xmlElement3 = (XmlElement)xmlElement2.SelectSingleNode("SocketClient");
			return Convert.ToInt32(xmlElement3.InnerText);
		}
	}

	/// <summary>
	/// 是否自动开启设备延迟日志
	/// </summary>
	/// <returns></returns>
	internal static bool AutoDelayLog
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return false;
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoDelayLog");
			return xmlElement2 != null && Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 设备延迟超过n毫秒时记录日志
	/// </summary>
	/// <returns></returns>
	internal static int DelayLogLimit
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("DelayLogLimit");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 占用内存超限时是否自动记录日志
	/// </summary>
	/// <returns></returns>
	internal static bool AutoMemoryLog
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return false;
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoMemoryLog");
			return xmlElement2 != null && Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 占用内存的上限(MB)，超限时记录日志
	/// </summary>
	/// <returns></returns>
	internal static int MemoryLogLimit
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return 1024;
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoMemoryLog");
			return (xmlElement2 != null) ? Convert.ToInt32(xmlElement2.Attributes["Limit"].Value) : 1024;
		}
	}

	/// <summary>
	/// 日志源类型（1:Sqlite;2:MySQL;）
	/// </summary>
	internal static int LogSourceType
	{
		get
		{
			if (_logSourceType == 0)
			{
				if (!File.Exists(SETTING_FILE_FULL_PATH))
				{
					return 1;
				}
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.Load(SETTING_FILE_FULL_PATH);
				XmlElement documentElement = xmlDocument.DocumentElement;
				XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
				if (xmlElement == null)
				{
					return 1;
				}
				XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("LogSourceType");
				_logSourceType = ((xmlElement2 == null) ? 1 : Convert.ToInt32(xmlElement2.InnerText));
			}
			return _logSourceType;
		}
	}

	/// <summary>
	/// 连接字符串（当日志源为MySQL时）
	/// </summary>
	internal static string ConnStr
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return "Data Source=127.0.0.1;Database=daq.log;User Id=root;Password=root;charset=utf8;pooling=true;Allow User Variables=True;SslMode=None;";
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("ConnStr");
			return (xmlElement2 != null) ? xmlElement2.InnerText : "Data Source=127.0.0.1;Database=daq.log;User Id=root;Password=root;charset=utf8;pooling=true;Allow User Variables=True;SslMode=None;";
		}
	}

	/// <summary>
	/// 保留最近n天的日志
	/// </summary>
	/// <returns></returns>
	internal static int LogLifetime
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return 7;
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("LogLifetime");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 查询日志的最大数量
	/// </summary>
	internal static int LOG_LIMITCOUNT
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Log");
			if (xmlElement == null)
			{
				return 100;
			}
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("LogLimitCount");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 是否自动最大化数据监控窗口
	/// </summary>
	/// <returns></returns>
	internal static bool AutoMaximizeMonitor
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoMaximizeMonitor");
			return Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 数据监控窗口每n个点位一组
	/// </summary>
	/// <returns></returns>
	internal static int MonitorGroupSize
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("MonitorGroupSize");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// Ping设备的Timeout值
	/// </summary>
	/// <returns></returns>
	internal static int PingDeviceTimeout
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("PingDeviceTimeout");
			return Convert.ToInt32(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 是否每隔n小时自动重启
	/// </summary>
	/// <returns></returns>
	internal static bool AutoRestartByInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoRestartByInterval");
			return xmlElement2 != null && Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 自动重启的频率（h）
	/// </summary>
	internal static int RestartInterval
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoRestartByInterval");
			return (xmlElement2 != null) ? Convert.ToInt32(xmlElement2.Attributes["Interval"].Value) : 24;
		}
	}

	/// <summary>
	/// 内存超限时是否自动重启
	/// </summary>
	/// <returns></returns>
	internal static bool AutoRestartByMemory
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoRestartByMemory");
			return xmlElement2 != null && Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// 自动重启的内存上限（MB）
	/// </summary>
	internal static int RestartMemoryLimit
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(SETTING_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("Other");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("AutoRestartByMemory");
			return (xmlElement2 != null) ? Convert.ToInt32(xmlElement2.Attributes["Limit"].Value) : 24;
		}
	}

	/// <summary>
	/// SocketServer监听到客户端信息后是否自动记录日志
	/// </summary>
	/// <returns></returns>
	internal static bool SocketServerNeedLog
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(CONFIG_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("SocketServer");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("NeedLog");
			return Convert.ToBoolean(xmlElement2.InnerText);
		}
	}

	/// <summary>
	/// SocketServer监听到客户端信息后执行方法的命名空间
	/// </summary>
	/// <returns></returns>
	internal static string SocketServerNamespace
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(CONFIG_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("SocketServer");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("Namespace");
			return (xmlElement2 != null) ? xmlElement2.InnerText : string.Empty;
		}
	}

	/// <summary>
	/// SocketServer监听到客户端信息后执行方法的类名
	/// </summary>
	/// <returns></returns>
	internal static string SocketServerClassName
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(CONFIG_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("SocketServer");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("ClassName");
			return xmlElement2.InnerText;
		}
	}

	/// <summary>
	/// SocketServer监听到客户端信息后执行方法的类名
	/// </summary>
	/// <returns></returns>
	internal static string SocketServerMethodName
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(CONFIG_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("SocketServer");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("MethodName");
			return xmlElement2.InnerText;
		}
	}

	/// <summary>
	/// SocketServer收发的消息标识
	/// </summary>
	/// <returns></returns>
	public static string SocketServerMsgIdentifier
	{
		get
		{
			XmlDocument xmlDocument = new XmlDocument();
			xmlDocument.Load(CONFIG_FILE_FULL_PATH);
			XmlElement documentElement = xmlDocument.DocumentElement;
			XmlElement xmlElement = (XmlElement)documentElement.SelectSingleNode("SocketServer");
			XmlElement xmlElement2 = (XmlElement)xmlElement.SelectSingleNode("Identifier");
			return xmlElement2.InnerText;
		}
	}

	/// <summary>
	/// 获取所有设备
	/// </summary>
	/// <returns></returns>
	public static List<Device> GetAllDevices()
	{
		List<Device> list = new List<Device>();
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Device")
				{
					XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
					Guid deviceId = new Guid(xElement.Attribute("Id").Value);
					if (list.Any((Device t) => t.Id == deviceId))
					{
						throw new Exception($"设备Id[{deviceId}]出现重复，请检查配置文件");
					}
					list.Add(GetDevice(xElement));
				}
			}
		}
		return list;
	}

	/// <summary>
	/// 获取指定设备
	/// </summary>
	/// <param name="deviceId">设备Id</param>
	/// <returns></returns>
	public static Device GetDevice(Guid deviceId)
	{
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "Device")
				{
					XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
					Guid guid = new Guid(xElement.Attribute("Id").Value);
					if (guid == deviceId)
					{
						return GetDevice(xElement);
					}
				}
			}
		}
		throw new Exception($"未在配置文件中找到对应的设备[DeviceId:{deviceId}]");
	}

	/// <summary>
	/// 获取指定设备
	/// </summary>
	/// <param name="eleDevice">设备XElement对象</param>
	/// <returns></returns>
	private static Device GetDevice(XElement eleDevice)
	{
		Device device = new Device();
		device.Id = new Guid(eleDevice.Attribute("Id").Value);
		device.Name = eleDevice.Attribute("Name").Value.Trim();
		device.Type = Convert.ToInt32(eleDevice.Element("Type").Value);
		device.Brand = Convert.ToInt32(eleDevice.Element("Brand").Value);
		device.Model = Convert.ToInt32(eleDevice.Element("Model").Value);
		device.Protocol = (EnumProtocol)Enum.Parse(typeof(EnumProtocol), eleDevice.Element("Protocol").Value, ignoreCase: true);
		device.IP = eleDevice.Element("IP").Value.Trim();
		device.Port = Convert.ToInt32(eleDevice.Element("Port").Value);
		device.Desc = eleDevice.Element("Desc").Value.Trim();
		Device device2 = device;
		XElement xElement = eleDevice.Element("Params");
		if (xElement != null)
		{
			XElement xElement2 = xElement.Element("Suffix");
			if (xElement2 != null)
			{
				device2.Suffix = xElement2.Value.Trim();
			}
			XElement xElement3 = xElement.Element("NeedAccount");
			if (xElement3 != null)
			{
				device2.NeedAccount = Convert.ToBoolean(xElement3.Value);
			}
			XElement xElement4 = xElement.Element("Account");
			if (xElement4 != null)
			{
				device2.Account = xElement4.Value.Trim();
			}
			XElement xElement5 = xElement.Element("Pwd");
			if (xElement5 != null)
			{
				device2.Pwd = xElement5.Value.Trim();
			}
			XElement xElement6 = xElement.Element("Rack");
			if (xElement6 != null)
			{
				device2.Rack = Convert.ToInt32(xElement6.Value);
			}
			XElement xElement7 = xElement.Element("Slot");
			if (xElement7 != null)
			{
				device2.Slot = Convert.ToInt32(xElement7.Value);
			}
			XElement xElement8 = xElement.Element("DataFormat");
			if (xElement8 != null)
			{
				device2.DataFormat = xElement8.Value.Trim();
			}
			XElement xElement9 = xElement.Element("AddressStartWithZero");
			if (xElement9 != null)
			{
				device2.AddressStartWithZero = Convert.ToBoolean(xElement9.Value);
			}
			XElement xElement10 = xElement.Element("IsStringReverse");
			if (xElement10 != null)
			{
				device2.IsStringReverse = Convert.ToBoolean(xElement10.Value);
			}
			XElement xElement11 = xElement.Element("Station");
			if (xElement11 != null)
			{
				device2.Station = Convert.ToInt32(xElement11.Value);
			}
			XElement xElement12 = xElement.Element("ComPort");
			if (xElement12 != null)
			{
				device2.ComPort = xElement12.Value.Trim();
			}
			XElement xElement13 = xElement.Element("BaudRate");
			if (xElement13 != null)
			{
				device2.BaudRate = Convert.ToInt32(xElement13.Value);
			}
			XElement xElement14 = xElement.Element("DataBits");
			if (xElement14 != null)
			{
				device2.DataBits = Convert.ToInt32(xElement14.Value);
			}
			XElement xElement15 = xElement.Element("StopBits");
			if (xElement15 != null)
			{
				device2.StopBits = Convert.ToInt32(xElement15.Value);
			}
			XElement xElement16 = xElement.Element("Parity");
			if (xElement16 != null)
			{
				device2.Parity = Convert.ToInt32(xElement16.Value);
			}
		}
		return device2;
	}

	/// <summary>
	/// 获取所有站点
	/// </summary>
	/// <returns></returns>
	internal static List<Station> GetAllStations()
	{
		List<Station> list = new List<Station>();
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType != XmlNodeType.Element || !(xmlReader.Name == "Stations"))
				{
					continue;
				}
				XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
				foreach (XElement item in xElement.Elements("Station"))
				{
					Guid stationId = new Guid(item.Attribute("Id").Value);
					if (list.Any((Station t) => t.Id == stationId))
					{
						throw new Exception($"站点Id[{stationId}]出现重复，请检查配置文件");
					}
					list.Add(GetStation(item));
				}
			}
		}
		return list;
	}

	/// <summary>
	/// 获取指定站点
	/// </summary>
	/// <param name="stationId">站点Id</param>
	/// <returns></returns>
	internal static Station GetStation(Guid stationId)
	{
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType != XmlNodeType.Element || !(xmlReader.Name == "Stations"))
				{
					continue;
				}
				XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
				foreach (XElement item in xElement.Elements("Station"))
				{
					Guid guid = new Guid(item.Attribute("Id").Value);
					if (guid == stationId)
					{
						return GetStation(item);
					}
				}
			}
		}
		throw new Exception($"未在配置文件中找到对应的站点[StationId:{stationId}]");
	}

	/// <summary>
	/// 获取指定站点
	/// </summary>
	/// <param name="eleStation">站点XElement对象</param>
	private static Station GetStation(XElement eleStation)
	{
		Station station = new Station
		{
			Id = new Guid(eleStation.Attribute("Id").Value),
			Name = eleStation.Attribute("Name").Value.Trim(),
			DefaultDeviceId = new Guid(eleStation.Element("DefaultDeviceId").Value),
			Desc = eleStation.Element("Desc").Value.Trim()
		};
		station.DAQItems = GetDAQItems(eleStation);
		station.DAQTasks = GetDAQTasks(eleStation, station.DAQItems);
		return station;
	}

	/// <summary>
	/// 根据站点获取所有采集项
	/// </summary>
	/// <param name="stationId">站点Id</param>
	/// <returns></returns>
	internal static List<DAQItem> GetDAQItems(Guid stationId)
	{
		List<DAQItem> list = new List<DAQItem>();
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType != XmlNodeType.Element || !(xmlReader.Name == "Stations"))
				{
					continue;
				}
				XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
				foreach (XElement item in xElement.Elements("Station"))
				{
					Guid guid = new Guid(item.Attribute("Id").Value);
					if (guid == stationId)
					{
						return GetDAQItems(item);
					}
				}
			}
		}
		throw new Exception($"未在配置文件中找到对应的站点[StationId:{stationId}]");
	}

	/// <summary>
	/// 根据站点获取所有采集项
	/// </summary>
	/// <param name="eleStation">站点XElement对象</param>
	/// <returns></returns>
	private static List<DAQItem> GetDAQItems(XElement eleStation)
	{
		List<DAQItem> list = new List<DAQItem>();
		if (eleStation.Element("DAQItems") != null)
		{
			Guid stationId = new Guid(eleStation.Attribute("Id").Value);
			foreach (XElement item in eleStation.Element("DAQItems").Elements("Item"))
			{
				Guid id = new Guid(item.Attribute("Id").Value);
				if (list.Any((DAQItem t) => t.Id == id))
				{
					throw new Exception(string.Format("站点[{0}]的采集项Id[{1}]出现重复，请检查配置文件", eleStation.Attribute("Name").Value, id));
				}
				list.Add(GetDAQItem(stationId, item));
			}
		}
		return list;
	}

	/// <summary>
	/// 获取指定采集项
	/// </summary>
	/// <param name="stationId"></param>
	/// <param name="daqItemId"></param>
	/// <returns></returns>
	internal static DAQItem GetDAQItem(Guid stationId, Guid daqItemId)
	{
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType != XmlNodeType.Element || !(xmlReader.Name == "Stations"))
				{
					continue;
				}
				XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
				foreach (XElement item in xElement.Elements("Station"))
				{
					Guid guid = new Guid(item.Attribute("Id").Value);
					if (!(guid == stationId))
					{
						continue;
					}
					string text = item.Attribute("Name").Value.Trim();
					if (item.Element("DAQItems") == null)
					{
						continue;
					}
					foreach (XElement item2 in item.Element("DAQItems").Elements("Item"))
					{
						Guid guid2 = new Guid(item2.Attribute("Id").Value);
						if (guid2 == daqItemId)
						{
							return GetDAQItem(stationId, item2);
						}
					}
					throw new Exception($"未在站点[StationId:{stationId}]中找到DAQItem[DAQItemId:{daqItemId}]");
				}
			}
		}
		throw new Exception($"未在配置文件中找到对应的站点[StationId:{stationId}]");
	}

	/// <summary>
	/// 获取指定采集项
	/// </summary>
	/// <param name="stationId"></param>
	/// <param name="eleDAQItem">采集项XElement对象</param>
	/// <returns></returns>
	private static DAQItem GetDAQItem(Guid stationId, XElement eleDAQItem)
	{
		DAQItem dAQItem = new DAQItem
		{
			Id = new Guid(eleDAQItem.Attribute("Id").Value),
			Name = eleDAQItem.Attribute("Name").Value.Trim(),
			Identifier = eleDAQItem.Element("Identifier").Value.Trim(),
			StationId = stationId,
			DeviceId = new Guid(eleDAQItem.Element("DeviceId").Value),
			DataType = eleDAQItem.Element("DataType").Value.Trim(),
			Desc = eleDAQItem.Element("Desc").Value.Trim()
		};
		if (eleDAQItem.Element("NodeId") != null)
		{
			dAQItem.NodeId = eleDAQItem.Element("NodeId").Value.Trim();
		}
		if (eleDAQItem.Element("Address") != null)
		{
			dAQItem.Address = eleDAQItem.Element("Address").Value.Trim();
		}
		if (eleDAQItem.Element("Length") != null)
		{
			dAQItem.Length = Convert.ToInt32(eleDAQItem.Element("Length").Value);
		}
		return dAQItem;
	}

	/// <summary>
	/// 根据站点获取所有任务
	/// </summary>
	/// <param name="stationId"></param>
	/// <returns></returns>
	internal static List<DAQTask> GetDAQTasks(Guid stationId)
	{
		List<DAQTask> list = new List<DAQTask>();
		using (XmlReader xmlReader = XmlReader.Create(CONFIG_FILE_FULL_PATH))
		{
			while (xmlReader.Read())
			{
				if (xmlReader.NodeType != XmlNodeType.Element || !(xmlReader.Name == "Stations"))
				{
					continue;
				}
				XElement xElement = XNode.ReadFrom(xmlReader) as XElement;
				foreach (XElement item in xElement.Elements("Station"))
				{
					Guid guid = new Guid(item.Attribute("Id").Value);
					if (guid == stationId)
					{
						List<DAQItem> dAQItems = GetDAQItems(item);
						return GetDAQTasks(item, dAQItems);
					}
				}
			}
		}
		throw new Exception($"未在配置文件中找到对应的站点[StationId:{stationId}]");
	}

	/// <summary>
	/// 根据站点获取所有任务
	/// </summary>
	/// <param name="eleStation">站点XElement对象</param>
	/// <param name="daqItems">当前工站的采集项集合</param>
	/// <returns></returns>
	private static List<DAQTask> GetDAQTasks(XElement eleStation, List<DAQItem> daqItems)
	{
		List<DAQTask> list = new List<DAQTask>();
		if (eleStation.Element("DAQTasks") != null)
		{
			Guid stationId = new Guid(eleStation.Attribute("Id").Value);
			foreach (XElement item in eleStation.Element("DAQTasks").Elements("Task"))
			{
				Guid taskId = new Guid(item.Attribute("Id").Value);
				if (list.Any((DAQTask t) => t.Id == taskId))
				{
					throw new Exception(string.Format("站点[{0}]的任务Id[{1}]出现重复，请检查配置文件", eleStation.Attribute("Name").Value, taskId));
				}
				DAQTask dAQTask = new DAQTask();
				dAQTask.Id = taskId;
				dAQTask.Name = item.Attribute("Name").Value.Trim();
				dAQTask.StationId = stationId;
				dAQTask.Launch = item.Element("Launch") == null || Convert.ToBoolean(item.Element("Launch").Value);
				dAQTask.NeedLog = Convert.ToBoolean(item.Element("NeedLog").Value);
				dAQTask.TriggerMode = (EnumTaskTriggerMode)Enum.Parse(typeof(EnumTaskTriggerMode), item.Element("TriggerMode").Value, ignoreCase: true);
				dAQTask.Desc = item.Element("Desc").Value.Trim();
				dAQTask.MultiConditionStrategy = item.Element("MultiConditionStrategy").Value.Trim();
				dAQTask.Namespace = ((item.Element("Namespace") != null) ? item.Element("Namespace").Value.Trim() : string.Empty);
				dAQTask.ClassName = item.Element("ClassName").Value.Trim();
				dAQTask.MethodName = item.Element("MethodName").Value.Trim();
				DAQTask dAQTask2 = dAQTask;
				if (item.Element("Interval") != null)
				{
					dAQTask2.Interval = Convert.ToInt32(item.Element("Interval").Value);
				}
				if (item.Element("SocketServerId") != null)
				{
					dAQTask2.SocketServerId = new Guid(item.Element("SocketServerId").Value);
				}
				dAQTask2.Conditions = new List<TaskCondition>();
				if (item.Element("Conditions") != null)
				{
					foreach (XElement item2 in item.Element("Conditions").Elements("Condition"))
					{
						Guid daqItemId3 = new Guid(item2.Element("DAQItemId").Value);
						dAQTask2.Conditions.Add(new TaskCondition
						{
							Id = new Guid(item2.Attribute("Id").Value),
							StationId = stationId,
							DAQItemId = daqItemId3,
							DAQItem = daqItems.FirstOrDefault((DAQItem t) => t.Id == daqItemId3),
							Operator = item2.Element("Operator").Value.Trim(),
							Value = item2.Element("Value").Value.Trim()
						});
					}
				}
				dAQTask2.Params = new List<TaskParam>();
				if (item.Element("Params") != null)
				{
					foreach (XElement item3 in item.Element("Params").Elements("Param"))
					{
						Guid daqItemId2 = new Guid(item3.Element("DAQItemId").Value);
						TaskParam taskParam = new TaskParam
						{
							Id = new Guid(item3.Attribute("Id").Value),
							StationId = stationId,
							DAQItemId = daqItemId2,
							DAQItem = daqItems.FirstOrDefault((DAQItem t) => t.Id == daqItemId2)
						};
						if (item3.Element("IsConst") != null)
						{
							taskParam.IsConst = Convert.ToBoolean(item3.Element("IsConst").Value);
							taskParam.Const = item3.Element("IsConst").Attribute("Const").Value.Trim();
						}
						if (item3.Element("SingleRead") != null)
						{
							taskParam.SingleRead = Convert.ToBoolean(item3.Element("SingleRead").Value);
							taskParam.DefaultValue = item3.Element("SingleRead").Attribute("DefaultValue").Value.Trim();
						}
						dAQTask2.Params.Add(taskParam);
					}
				}
				dAQTask2.Writebacks = new List<TaskWriteback>();
				if (item.Element("Writebacks") != null)
				{
					foreach (XElement item4 in item.Element("Writebacks").Elements("Writeback"))
					{
						Guid daqItemId = new Guid(item4.Element("DAQItemId").Value);
						dAQTask2.Writebacks.Add(new TaskWriteback
						{
							Id = new Guid(item4.Attribute("Id").Value),
							StationId = stationId,
							DAQItemId = daqItemId,
							DAQItem = daqItems.FirstOrDefault((DAQItem t) => t.Id == daqItemId),
							Content = item4.Element("Content").Value.Trim(),
							ContentSource = item4.Element("ContentSource").Value.Trim()
						});
					}
				}
				bool socketMsgAsParam = false;
				string socketMsgIdentifier = string.Empty;
				XElement xElement = item.Element("SocketParam");
				if (xElement != null)
				{
					socketMsgAsParam = Convert.ToBoolean(xElement.Attribute("AsParam").Value);
					socketMsgIdentifier = xElement.Element("Identifier").Value.Trim();
				}
				bool writebackSocketMsg = false;
				string socketMsgWritebackContent = string.Empty;
				string socketMsgWritebackSource = string.Empty;
				bool socketMsgWritebackIsString = true;
				XElement xElement2 = item.Element("SocketWriteback");
				if (xElement2 != null)
				{
					writebackSocketMsg = Convert.ToBoolean(xElement2.Attribute("Writeback").Value);
					socketMsgWritebackContent = xElement2.Element("Content").Value.Trim();
					socketMsgWritebackSource = xElement2.Element("ContentSource").Value.Trim();
					socketMsgWritebackIsString = Convert.ToBoolean(xElement2.Element("IsString").Value);
				}
				dAQTask2.SocketMsgAsParam = socketMsgAsParam;
				dAQTask2.SocketMsgIdentifier = socketMsgIdentifier;
				dAQTask2.WritebackSocketMsg = writebackSocketMsg;
				dAQTask2.SocketMsgWritebackContent = socketMsgWritebackContent;
				dAQTask2.SocketMsgWritebackSource = socketMsgWritebackSource;
				dAQTask2.SocketMsgWritebackIsString = socketMsgWritebackIsString;
				list.Add(dAQTask2);
			}
		}
		return list;
	}

	/// <summary>
	/// ReadValues
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="device">设备</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">读取到的值</param>
	/// <param name="errMsg">错误信息</param>
	/// <param name="structInsBuffer">动态类实例的集合，可以减少循环读取OPCUA结构体的性能消耗</param>
	/// <returns></returns>
	internal static bool ReadValues(object connectionIns, Device device, List<DAQItem> daqItems, out List<object> values, out string errMsg, List<object> structInsBuffer = null)
	{
		bool result = false;
		errMsg = string.Empty;
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
			result = ReadValues_By_OPCUA((OpcUaClient)connectionIns, device, daqItems.Select((DAQItem t) => t.NodeId).ToList(), out values, out errMsg, structInsBuffer);
			break;
		case EnumProtocol.S7:
			result = ReadValues_By_S7((SiemensS7Net)connectionIns, daqItems, out values, out errMsg);
			break;
		case EnumProtocol.ModbusTcp:
			result = ReadValues_By_ModbusTcp((ModbusTcpNet)connectionIns, daqItems, out values, out errMsg);
			break;
		case EnumProtocol.ModbusRtu:
			result = ReadValues_By_ModbusRtu((ModbusRtu)connectionIns, daqItems, out values, out errMsg);
			break;
		case EnumProtocol.Socket:
			values = null;
			break;
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		}
		return result;
	}

	public static bool ReadValues(Device device, List<DAQItem> daqItems, out List<object> values, out string errMsg, List<object> structInsBuffer = null)
	{
		object connection = new RemotingHelper().GetConnection(device);
		return ReadValues(connection, device, daqItems, out values, out errMsg, structInsBuffer);
	}

	/// <summary>
	/// WriteValues
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="device">设备</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">写入的内容</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	internal static bool WriteValues(object connectionIns, Device device, List<DAQItem> daqItems, List<object> values, out string errMsg)
	{
		bool result = false;
		errMsg = string.Empty;
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
		{
			List<object> list = new List<object>();
			for (int i = 0; i < values.Count; i++)
			{
				if (typeof(ICollection).IsAssignableFrom(values[i].GetType()))
				{
					list.Add((ICollection)values[i]);
					continue;
				}
				if (daqItems[i].DataType.ToUpper() == "BOOLEAN")
				{
					daqItems[i].DataType = "Bool";
				}
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItems[i].DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
					list.Add(Convert.ToInt16(values[i]));
					break;
				case EnumDataType.UInt16:
					list.Add(Convert.ToUInt16(values[i]));
					break;
				case EnumDataType.Int32:
					list.Add(Convert.ToInt32(values[i]));
					break;
				case EnumDataType.Int64:
					list.Add(Convert.ToInt64(values[i]));
					break;
				case EnumDataType.Single:
					list.Add(Convert.ToSingle(values[i]));
					break;
				case EnumDataType.Double:
					list.Add(Convert.ToDouble(values[i]));
					break;
				case EnumDataType.Bool:
					list.Add(Convert.ToBoolean(values[i]));
					break;
				case EnumDataType.String:
					list.Add(values[i].ToString());
					break;
				case EnumDataType.DateTime:
					list.Add(Convert.ToDateTime(values[i]));
					break;
				case EnumDataType.Byte:
					list.Add(Convert.ToByte(values[i]));
					break;
				default:
					throw new Exception("未知的数据类型[" + daqItems[i].DataType + "]");
				}
			}
			result = WriteValues_By_OPCUA((OpcUaClient)connectionIns, daqItems.Select((DAQItem t) => t.NodeId).ToList(), list, (EnumBrand)device.Brand, out errMsg);
			break;
		}
		case EnumProtocol.S7:
			result = WriteValues_By_S7((SiemensS7Net)connectionIns, daqItems, values, out errMsg);
			break;
		case EnumProtocol.ModbusTcp:
			result = WriteValues_By_ModbusTcp((ModbusTcpNet)connectionIns, daqItems, values, out errMsg);
			break;
		case EnumProtocol.ModbusRtu:
			result = WriteValues_By_ModbusRtu((ModbusRtu)connectionIns, daqItems, values, out errMsg);
			break;
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		case EnumProtocol.Socket:
			break;
		}
		return result;
	}

	/// <summary>
	/// OPCUA ReadValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="device">设备</param>
	/// <param name="nodeIds">NodeIds</param>
	/// <param name="values">读取到的值</param>
	/// <param name="errMsg">错误信息</param>
	/// <param name="structInsBuffer">动态实例缓存，可以减少循环读取OPCUA结构体的性能消耗</param>
	/// <returns></returns>
	private static bool ReadValues_By_OPCUA(OpcUaClient connectionIns, Device device, List<string> nodeIds, out List<object> values, out string errMsg, List<object> structInsBuffer = null)
	{
		bool result = false;
		values = new List<object>();
		errMsg = string.Empty;
		if (structInsBuffer == null)
		{
			structInsBuffer = new List<object>();
		}
		try
		{
			switch (device.Brand)
			{
			case 0:
			case 1:
			{
				List<DataValue> list16 = connectionIns.ReadNodes(nodeIds.Select((string t) => new NodeId(t)).ToArray());
				if (list16.Any((DataValue t) => StatusCode.IsNotGood(t.StatusCode)))
				{
					errMsg = list16.FirstOrDefault((DataValue t) => StatusCode.IsNotGood(t.StatusCode)).StatusCode.ToString();
					values.Add(errMsg);
					break;
				}
				object obj3 = null;
				for (int i = 0; i < list16.Count; i++)
				{
					obj3 = null;
					string lastNodeName = string.Empty;
					if (nodeIds[i].Contains("."))
					{
						lastNodeName = nodeIds[i].Substring(nodeIds[i].LastIndexOf(".") + 1);
					}
					else
					{
						lastNodeName = nodeIds[i].Substring(nodeIds[i].IndexOf(";s=") + 3);
					}
					int num3 = StructHelper.IsArray(lastNodeName, out lastNodeName);
					lastNodeName = lastNodeName.Trim('"');
					if (list16[i].WrappedValue.TypeInfo.BuiltInType == BuiltInType.ExtensionObject)
					{
						object obj4 = structInsBuffer.FirstOrDefault((object t) => t.GetType().Name == lastNodeName);
						if (obj4 == null)
						{
							List<StructItem> structItems2 = StructHelper.GetStructItems(connectionIns.Session, nodeIds[i], list16[i].WrappedValue.Value);
							if (list16[i].WrappedValue.Value is ExtensionObject)
							{
								obj4 = RecursiveCreateObj(device.Id, nodeIds[i], lastNodeName, structItems2);
							}
							else if (list16[i].WrappedValue.Value is ExtensionObject[])
							{
								List<object> list17 = new List<object>();
								foreach (List<StructItem> item in (List<List<StructItem>>)structItems2[0].Value)
								{
									list17.Add(RecursiveCreateObj(device.Id, nodeIds[i], lastNodeName, item));
								}
								obj4 = list17;
							}
							structInsBuffer.Add(obj4);
						}
						obj3 = ((!(list16[i].WrappedValue.Value is ExtensionObject[])) ? obj4 : ((num3 < 0) ? obj4 : ((List<object>)obj4)[num3]));
					}
					else if (list16[i].WrappedValue.Value.GetType().IsArray)
					{
						Type type2 = list16[i].WrappedValue.Value.GetType();
						if (type2 == typeof(short[]))
						{
							List<short> list18 = new List<short>();
							foreach (object item2 in (Array)list16[i].WrappedValue.Value)
							{
								list18.Add(Convert.ToInt16(item2));
							}
							obj3 = ((num3 < 0) ? list18 : ((object)list18[num3]));
						}
						else if (type2 == typeof(int[]))
						{
							List<int> list19 = new List<int>();
							foreach (object item3 in (Array)list16[i].WrappedValue.Value)
							{
								list19.Add(Convert.ToInt32(item3));
							}
							obj3 = ((num3 < 0) ? list19 : ((object)list19[num3]));
						}
						else if (type2 == typeof(long[]))
						{
							List<long> list20 = new List<long>();
							foreach (object item4 in (Array)list16[i].WrappedValue.Value)
							{
								list20.Add(Convert.ToInt64(item4));
							}
							obj3 = ((num3 < 0) ? list20 : ((object)list20[num3]));
						}
						else if (type2 == typeof(ushort[]))
						{
							List<ushort> list21 = new List<ushort>();
							foreach (object item5 in (Array)list16[i].WrappedValue.Value)
							{
								list21.Add(Convert.ToUInt16(item5));
							}
							obj3 = ((num3 < 0) ? list21 : ((object)list21[num3]));
						}
						else if (type2 == typeof(uint[]))
						{
							List<uint> list22 = new List<uint>();
							foreach (object item6 in (Array)list16[i].WrappedValue.Value)
							{
								list22.Add(Convert.ToUInt32(item6));
							}
							obj3 = ((num3 < 0) ? list22 : ((object)list22[num3]));
						}
						else if (type2 == typeof(ulong[]))
						{
							List<ulong> list23 = new List<ulong>();
							foreach (object item7 in (Array)list16[i].WrappedValue.Value)
							{
								list23.Add(Convert.ToUInt64(item7));
							}
							obj3 = ((num3 < 0) ? list23 : ((object)list23[num3]));
						}
						else if (type2 == typeof(bool[]))
						{
							List<bool> list24 = new List<bool>();
							foreach (object item8 in (Array)list16[i].WrappedValue.Value)
							{
								list24.Add(Convert.ToBoolean(item8));
							}
							obj3 = ((num3 < 0) ? list24 : ((object)list24[num3]));
						}
						else if (type2 == typeof(byte[]))
						{
							try
							{
								obj3 = DateTime.ParseExact(BitConverter.ToString((byte[])list16[i].WrappedValue.Value).Replace("-", ""), "yyMMddHHmmssffff", CultureInfo.InvariantCulture);
							}
							catch
							{
								List<byte> list25 = new List<byte>();
								foreach (object item9 in (Array)list16[i].WrappedValue.Value)
								{
									list25.Add(Convert.ToByte(item9));
								}
								obj3 = ((num3 < 0) ? list25 : ((object)list25[num3]));
							}
						}
						else if (type2 == typeof(float[]))
						{
							List<float> list26 = new List<float>();
							foreach (object item10 in (Array)list16[i].WrappedValue.Value)
							{
								list26.Add(Convert.ToSingle(item10));
							}
							obj3 = ((num3 < 0) ? list26 : ((object)list26[num3]));
						}
						else if (type2 == typeof(double[]))
						{
							List<double> list27 = new List<double>();
							foreach (object item11 in (Array)list16[i].WrappedValue.Value)
							{
								list27.Add(Convert.ToDouble(item11));
							}
							obj3 = ((num3 < 0) ? list27 : ((object)list27[num3]));
						}
						else if (type2 == typeof(DateTime[]))
						{
							List<DateTime> list28 = new List<DateTime>();
							foreach (object item12 in (Array)list16[i].WrappedValue.Value)
							{
								list28.Add(Convert.ToDateTime(item12));
							}
							obj3 = ((num3 < 0) ? list28 : ((object)list28[num3]));
						}
						else if (type2 == typeof(string[]))
						{
							List<string> list29 = new List<string>();
							foreach (object item13 in (Array)list16[i].WrappedValue.Value)
							{
								list29.Add(item13.ToString());
							}
							obj3 = ((num3 < 0) ? ((IEnumerable)list29) : ((IEnumerable)list29[num3]));
						}
						else
						{
							List<object> list30 = new List<object>();
							foreach (object item14 in (Array)list16[i].WrappedValue.Value)
							{
								list30.Add(item14);
							}
							obj3 = ((num3 < 0) ? list30 : list30[num3]);
						}
					}
					else if (list16[i].WrappedValue.Value.GetType() == typeof(Matrix))
					{
						List<DateTime> list31 = new List<DateTime>();
						Matrix matrix = (Matrix)list16[i].WrappedValue.Value;
						int num4 = matrix.Dimensions[0];
						int num5 = matrix.Dimensions[1];
						for (int j = 0; j < num4; j++)
						{
							byte[] array = new byte[num5];
							for (int k = 0; k < num5; k++)
							{
								array[k] = ((byte[])matrix.Elements)[j * num5 + k];
							}
							list31.Add(DateTime.ParseExact(BitConverter.ToString(array).Replace("-", ""), "yyMMddHHmmssffff", CultureInfo.InvariantCulture));
						}
						obj3 = list31;
					}
					else
					{
						obj3 = list16[i].WrappedValue.Value;
					}
					values.Add(obj3);
					result = true;
				}
				break;
			}
			case 2:
			{
				int num = 0;
				object obj = null;
				foreach (string nodeId in nodeIds)
				{
					obj = null;
					string empty = string.Empty;
					empty = ((!nodeId.Contains(".")) ? nodeId : nodeId.Substring(0, nodeId.IndexOf(".")));
					string globalValueName = empty.Substring(empty.IndexOf(";s=") + 3);
					int num2 = StructHelper.IsArray(globalValueName, out globalValueName);
					DataValue dataValue = connectionIns.ReadNode(new NodeId(empty));
					if (StatusCode.IsGood(dataValue.StatusCode))
					{
						if (dataValue.WrappedValue.TypeInfo.BuiltInType == BuiltInType.ExtensionObject)
						{
							object obj2 = structInsBuffer.FirstOrDefault((object t) => t.GetType().Name == globalValueName);
							if (obj2 == null)
							{
								List<StructItem> structItems = StructHelper.GetStructItems(connectionIns.Session, empty, dataValue.WrappedValue.Value);
								if (dataValue.WrappedValue.Value is ExtensionObject)
								{
									obj2 = RecursiveCreateObj(device.Id, empty, globalValueName, structItems);
								}
								else if (dataValue.WrappedValue.Value is ExtensionObject[])
								{
									List<object> list = new List<object>();
									foreach (List<StructItem> item15 in (List<List<StructItem>>)structItems[0].Value)
									{
										list.Add(RecursiveCreateObj(device.Id, empty, globalValueName, item15));
									}
									obj2 = list;
								}
								structInsBuffer.Add(obj2);
							}
							obj = ((!(dataValue.WrappedValue.Value is ExtensionObject[])) ? obj2 : ((num2 < 0) ? obj2 : ((List<object>)obj2)[num2]));
						}
						else if (dataValue.WrappedValue.Value.GetType().IsArray)
						{
							Type type = dataValue.WrappedValue.Value.GetType();
							if (type == typeof(short[]))
							{
								List<short> list2 = new List<short>();
								foreach (object item16 in (Array)dataValue.WrappedValue.Value)
								{
									list2.Add(Convert.ToInt16(item16));
								}
								obj = ((num2 < 0) ? list2 : ((object)list2[num2]));
							}
							else if (type == typeof(int[]))
							{
								List<int> list3 = new List<int>();
								foreach (object item17 in (Array)dataValue.WrappedValue.Value)
								{
									list3.Add(Convert.ToInt32(item17));
								}
								obj = ((num2 < 0) ? list3 : ((object)list3[num2]));
							}
							else if (type == typeof(long[]))
							{
								List<long> list4 = new List<long>();
								foreach (object item18 in (Array)dataValue.WrappedValue.Value)
								{
									list4.Add(Convert.ToInt64(item18));
								}
								obj = ((num2 < 0) ? list4 : ((object)list4[num2]));
							}
							else if (type == typeof(ushort[]))
							{
								List<ushort> list5 = new List<ushort>();
								foreach (object item19 in (Array)dataValue.WrappedValue.Value)
								{
									list5.Add(Convert.ToUInt16(item19));
								}
								obj = ((num2 < 0) ? list5 : ((object)list5[num2]));
							}
							else if (type == typeof(uint[]))
							{
								List<uint> list6 = new List<uint>();
								foreach (object item20 in (Array)dataValue.WrappedValue.Value)
								{
									list6.Add(Convert.ToUInt32(item20));
								}
								obj = ((num2 < 0) ? list6 : ((object)list6[num2]));
							}
							else if (type == typeof(ulong[]))
							{
								List<ulong> list7 = new List<ulong>();
								foreach (object item21 in (Array)dataValue.WrappedValue.Value)
								{
									list7.Add(Convert.ToUInt64(item21));
								}
								obj = ((num2 < 0) ? list7 : ((object)list7[num2]));
							}
							else if (type == typeof(bool[]))
							{
								List<bool> list8 = new List<bool>();
								foreach (object item22 in (Array)dataValue.WrappedValue.Value)
								{
									list8.Add(Convert.ToBoolean(item22));
								}
								obj = ((num2 < 0) ? list8 : ((object)list8[num2]));
							}
							else if (type == typeof(byte[]))
							{
								List<byte> list9 = new List<byte>();
								foreach (object item23 in (Array)dataValue.WrappedValue.Value)
								{
									list9.Add(Convert.ToByte(item23));
								}
								obj = ((num2 < 0) ? list9 : ((object)list9[num2]));
							}
							else if (type == typeof(float[]))
							{
								List<float> list10 = new List<float>();
								foreach (object item24 in (Array)dataValue.WrappedValue.Value)
								{
									list10.Add(Convert.ToSingle(item24));
								}
								obj = ((num2 < 0) ? list10 : ((object)list10[num2]));
							}
							else if (type == typeof(double[]))
							{
								List<double> list11 = new List<double>();
								foreach (object item25 in (Array)dataValue.WrappedValue.Value)
								{
									list11.Add(Convert.ToDouble(item25));
								}
								obj = ((num2 < 0) ? list11 : ((object)list11[num2]));
							}
							else if (type == typeof(DateTime[]))
							{
								List<DateTime> list12 = new List<DateTime>();
								foreach (object item26 in (Array)dataValue.WrappedValue.Value)
								{
									list12.Add(Convert.ToDateTime(item26));
								}
								obj = ((num2 < 0) ? list12 : ((object)list12[num2]));
							}
							else if (type == typeof(string[]))
							{
								List<string> list13 = new List<string>();
								foreach (object item27 in (Array)dataValue.WrappedValue.Value)
								{
									list13.Add(item27.ToString());
								}
								obj = ((num2 < 0) ? ((IEnumerable)list13) : ((IEnumerable)list13[num2]));
							}
							else
							{
								List<object> list14 = new List<object>();
								foreach (object item28 in (Array)dataValue.WrappedValue.Value)
								{
									list14.Add(item28);
								}
								obj = ((num2 < 0) ? list14 : list14[num2]);
							}
						}
						else
						{
							obj = dataValue.WrappedValue.Value;
						}
						if (nodeId.Contains("."))
						{
							string text = nodeId.Substring(nodeId.IndexOf(".") + 1);
							List<string> list15 = text.Split(new string[1] { "." }, StringSplitOptions.RemoveEmptyEntries).ToList();
							if (list15.Count > 0)
							{
								int stepIndex = 0;
								obj = RecursiveGetValue(obj, list15, ref stepIndex);
							}
						}
						values.Add(obj);
						num++;
					}
					else
					{
						errMsg = dataValue.StatusCode.ToString();
						values.Add(errMsg);
					}
				}
				result = num == nodeIds.Count;
				break;
			}
			default:
				throw new Exception("未知的品牌[" + device.BrandName + "]");
			}
		}
		catch (Exception ex)
		{
			result = false;
			errMsg = ex.Message;
		}
		return result;
	}

	/// <summary>
	/// OPCUA递归创建对象
	/// </summary>
	/// <param name="deviceId">设备Id，用于在缓存中区分动态类所属设备，防止不同设备中存在相同NodeId、相同名称的结构体</param>
	/// <param name="virtualNodeId">不包含数组下标的NodeId，用于在缓存中将动态类与NodeId一一对应，防止不同设备中存在相同NodeId（同设备下，相同NodeId结构体的数据结构一定相同，数组中不同元素的数据结构也一定相同）</param>
	/// <param name="className">类名</param>
	/// <param name="items">StructItem集合形式的属性值</param>
	/// <returns>动态类的实例</returns>
	private static object RecursiveCreateObj(Guid deviceId, string virtualNodeId, string className, List<StructItem> items)
	{
		Dictionary<string, Type> dictionary = new Dictionary<string, Type>();
		foreach (StructItem item in items)
		{
			if (item.DataType == typeof(object))
			{
				item.Value = RecursiveCreateObj(deviceId, virtualNodeId + "." + item.Name, item.Name, (List<StructItem>)item.Value);
			}
			else if (item.DataType == typeof(List<object>))
			{
				List<object> list = new List<object>();
				foreach (List<StructItem> item2 in (List<List<StructItem>>)item.Value)
				{
					list.Add(RecursiveCreateObj(deviceId, virtualNodeId + "." + item.Name, item.Name, item2));
				}
				item.Value = list;
			}
			dictionary.Add(item.Name, item.DataType);
		}
		Type type;
		if (DYNAMICCLASS_POOL.Any((KeyValuePair<Guid, Dictionary<string, Type>> t) => t.Key == deviceId && DYNAMICCLASS_POOL[deviceId].Any((KeyValuePair<string, Type> x) => x.Key == virtualNodeId && DYNAMICCLASS_POOL[deviceId][virtualNodeId].Name == className)))
		{
			type = DYNAMICCLASS_POOL.FirstOrDefault((KeyValuePair<Guid, Dictionary<string, Type>> t) => t.Key == deviceId).Value.FirstOrDefault((KeyValuePair<string, Type> t) => t.Key == virtualNodeId).Value;
			PropertyInfo[] properties = type.GetProperties();
			if (properties.Length != dictionary.Count)
			{
				type = DynamicClassHelper.CreateType(className, dictionary);
				DYNAMICCLASS_POOL[deviceId][virtualNodeId] = type;
			}
			else
			{
				foreach (KeyValuePair<string, Type> newPropery in dictionary)
				{
					if (!properties.Any((PropertyInfo t) => t.Name == newPropery.Key && t.PropertyType == newPropery.Value))
					{
						type = DynamicClassHelper.CreateType(className, dictionary);
						DYNAMICCLASS_POOL[deviceId][virtualNodeId] = type;
						break;
					}
				}
			}
		}
		else
		{
			type = DynamicClassHelper.CreateType(className, dictionary);
			if (DYNAMICCLASS_POOL.ContainsKey(deviceId))
			{
				if (DYNAMICCLASS_POOL[deviceId].ContainsKey(virtualNodeId))
				{
					DYNAMICCLASS_POOL[deviceId][virtualNodeId] = type;
					string message = $"设备[{deviceId}]中发现了同一NodeId[{virtualNodeId}]不同动态类名[{className}]的情况";
					throw new Exception(message);
				}
				DYNAMICCLASS_POOL[deviceId].Add(virtualNodeId, type);
			}
			else
			{
				DYNAMICCLASS_POOL.Add(deviceId, new Dictionary<string, Type> { { virtualNodeId, type } });
			}
		}
		object obj = DynamicClassHelper.CreateInstance(type);
		foreach (StructItem item3 in items)
		{
			Type type2 = item3.Value.GetType();
			if (item3.DataType == typeof(DateTime) && type2 != typeof(DateTime))
			{
				item3.Value = Convert.ToDateTime(item3.Value);
			}
			else if (item3.DataType == typeof(List<short>) && type2 != typeof(List<short>))
			{
				List<short> list2 = new List<short>();
				foreach (object item4 in (IEnumerable<object>)item3.Value)
				{
					list2.Add(Convert.ToInt16(item4));
				}
				item3.Value = list2;
			}
			else if (item3.DataType == typeof(List<int>) && type2 != typeof(List<int>))
			{
				List<int> list3 = new List<int>();
				foreach (object item5 in (IEnumerable<object>)item3.Value)
				{
					list3.Add(Convert.ToInt32(item5));
				}
				item3.Value = list3;
			}
			else if (item3.DataType == typeof(List<long>) && type2 != typeof(List<long>))
			{
				List<long> list4 = new List<long>();
				foreach (object item6 in (IEnumerable<object>)item3.Value)
				{
					list4.Add(Convert.ToInt64(item6));
				}
				item3.Value = list4;
			}
			else if (item3.DataType == typeof(List<ushort>) && type2 != typeof(List<ushort>))
			{
				List<ushort> list5 = new List<ushort>();
				foreach (object item7 in (IEnumerable<object>)item3.Value)
				{
					list5.Add(Convert.ToUInt16(item7));
				}
				item3.Value = list5;
			}
			else if (item3.DataType == typeof(List<uint>) && type2 != typeof(List<uint>))
			{
				List<uint> list6 = new List<uint>();
				foreach (object item8 in (IEnumerable<object>)item3.Value)
				{
					list6.Add(Convert.ToUInt32(item8));
				}
				item3.Value = list6;
			}
			else if (item3.DataType == typeof(List<ulong>) && type2 != typeof(List<ulong>))
			{
				List<ulong> list7 = new List<ulong>();
				foreach (object item9 in (IEnumerable<object>)item3.Value)
				{
					list7.Add(Convert.ToUInt64(item9));
				}
				item3.Value = list7;
			}
			else if (item3.DataType == typeof(List<bool>) && type2 != typeof(List<bool>))
			{
				List<bool> list8 = new List<bool>();
				foreach (object item10 in (IEnumerable<object>)item3.Value)
				{
					list8.Add(Convert.ToBoolean(item10));
				}
				item3.Value = list8;
			}
			else if (item3.DataType == typeof(List<byte>) && type2 != typeof(List<byte>))
			{
				List<byte> list9 = new List<byte>();
				foreach (object item11 in (IEnumerable<object>)item3.Value)
				{
					list9.Add(Convert.ToByte(item11));
				}
				item3.Value = list9;
			}
			else if (item3.DataType == typeof(List<float>) && type2 != typeof(List<float>))
			{
				List<float> list10 = new List<float>();
				foreach (object item12 in (IEnumerable<object>)item3.Value)
				{
					list10.Add(Convert.ToSingle(item12));
				}
				item3.Value = list10;
			}
			else if (item3.DataType == typeof(List<double>) && type2 != typeof(List<double>))
			{
				List<double> list11 = new List<double>();
				foreach (object item13 in (IEnumerable<object>)item3.Value)
				{
					list11.Add(Convert.ToDouble(item13));
				}
				item3.Value = list11;
			}
			else if (item3.DataType == typeof(List<DateTime>) && type2 != typeof(List<DateTime>))
			{
				List<DateTime> list12 = new List<DateTime>();
				foreach (object item14 in (IEnumerable<object>)item3.Value)
				{
					list12.Add(Convert.ToDateTime(item14));
				}
				item3.Value = list12;
			}
			else if (item3.DataType == typeof(List<string>) && type2 != typeof(List<string>))
			{
				List<string> list13 = new List<string>();
				foreach (object item15 in (IEnumerable<object>)item3.Value)
				{
					list13.Add(item15.ToString());
				}
				item3.Value = list13;
			}
			else if (item3.DataType == typeof(List<object>) && type2 != typeof(List<object>))
			{
				List<object> source = (List<object>)item3.Value;
				if (source.Any((object t) => t != null))
				{
					type2 = source.FirstOrDefault((object t) => t != null).GetType();
					if (type2 == typeof(short))
					{
						List<short> list14 = new List<short>();
						foreach (object item16 in (IEnumerable<object>)item3.Value)
						{
							list14.Add(Convert.ToInt16(item16));
						}
						item3.Value = list14;
					}
					else if (type2 == typeof(int))
					{
						List<int> list15 = new List<int>();
						foreach (object item17 in (IEnumerable<object>)item3.Value)
						{
							list15.Add(Convert.ToInt32(item17));
						}
						item3.Value = list15;
					}
					else if (type2 == typeof(long))
					{
						List<long> list16 = new List<long>();
						foreach (object item18 in (IEnumerable<object>)item3.Value)
						{
							list16.Add(Convert.ToInt64(item18));
						}
						item3.Value = list16;
					}
					else if (type2 == typeof(ushort))
					{
						List<ushort> list17 = new List<ushort>();
						foreach (object item19 in (IEnumerable<object>)item3.Value)
						{
							list17.Add(Convert.ToUInt16(item19));
						}
						item3.Value = list17;
					}
					else if (type2 == typeof(uint))
					{
						List<uint> list18 = new List<uint>();
						foreach (object item20 in (IEnumerable<object>)item3.Value)
						{
							list18.Add(Convert.ToUInt32(item20));
						}
						item3.Value = list18;
					}
					else if (type2 == typeof(ulong))
					{
						List<ulong> list19 = new List<ulong>();
						foreach (object item21 in (IEnumerable<object>)item3.Value)
						{
							list19.Add(Convert.ToUInt64(item21));
						}
						item3.Value = list19;
					}
					else if (type2 == typeof(bool))
					{
						List<bool> list20 = new List<bool>();
						foreach (object item22 in (IEnumerable<object>)item3.Value)
						{
							list20.Add(Convert.ToBoolean(item22));
						}
						item3.Value = list20;
					}
					else if (type2 == typeof(byte))
					{
						List<byte> list21 = new List<byte>();
						foreach (object item23 in (IEnumerable<object>)item3.Value)
						{
							list21.Add(Convert.ToByte(item23));
						}
						item3.Value = list21;
					}
					else if (type2 == typeof(float))
					{
						List<float> list22 = new List<float>();
						foreach (object item24 in (IEnumerable<object>)item3.Value)
						{
							list22.Add(Convert.ToSingle(item24));
						}
						item3.Value = list22;
					}
					else if (type2 == typeof(double))
					{
						List<double> list23 = new List<double>();
						foreach (object item25 in (IEnumerable<object>)item3.Value)
						{
							list23.Add(Convert.ToDouble(item25));
						}
						item3.Value = list23;
					}
					else if (type2 == typeof(DateTime))
					{
						List<DateTime> list24 = new List<DateTime>();
						foreach (object item26 in (IEnumerable<object>)item3.Value)
						{
							list24.Add(Convert.ToDateTime(item26));
						}
						item3.Value = list24;
					}
					else if (type2 == typeof(string))
					{
						List<string> list25 = new List<string>();
						foreach (object item27 in (IEnumerable<object>)item3.Value)
						{
							list25.Add(item27.ToString());
						}
						item3.Value = list25;
					}
				}
			}
			DynamicClassHelper.SetValue(type, obj, item3.Name, item3.Value);
		}
		return obj;
	}

	/// <summary>
	/// OPCUA 递归获取子属性的值
	/// </summary>
	/// <param name="instance">实例</param>
	/// <param name="stepProperties">依次获取值的子属性名称集合</param>
	/// <param name="stepIndex">子属性序号</param>
	/// <returns></returns>
	private static object RecursiveGetValue(object instance, List<string> stepProperties, ref int stepIndex)
	{
		string text = stepProperties[stepIndex];
		int num = -1;
		if (text.Contains("["))
		{
			num = Convert.ToInt32(text.Substring(text.IndexOf("[") + 1, text.IndexOf("]") - text.IndexOf("[") - 1));
			text = text.Substring(0, text.IndexOf("["));
		}
		if (instance.GetType().GetProperty(text) == null)
		{
			throw new Exception("BadNodeIdUnknown");
		}
		object obj = DynamicClassHelper.GetValue(instance.GetType(), instance, text);
		if (num >= 0)
		{
			Type type = obj.GetType();
			obj = ((type == typeof(List<short>)) ? ((object)((List<short>)obj)[num]) : ((type == typeof(List<int>)) ? ((object)((List<int>)obj)[num]) : ((type == typeof(List<long>)) ? ((object)((List<long>)obj)[num]) : ((type == typeof(List<ushort>)) ? ((object)((List<ushort>)obj)[num]) : ((type == typeof(List<uint>)) ? ((object)((List<uint>)obj)[num]) : ((type == typeof(List<ulong>)) ? ((object)((List<ulong>)obj)[num]) : ((type == typeof(List<bool>)) ? ((object)((List<bool>)obj)[num]) : ((type == typeof(List<byte>)) ? ((object)((List<byte>)obj)[num]) : ((type == typeof(List<float>)) ? ((object)((List<float>)obj)[num]) : ((type == typeof(List<double>)) ? ((object)((List<double>)obj)[num]) : ((type == typeof(List<DateTime>)) ? ((object)((List<DateTime>)obj)[num]) : ((!(type == typeof(List<string>))) ? ((List<object>)obj)[num] : ((List<string>)obj)[num]))))))))))));
		}
		if (stepProperties.Count - stepIndex > 1)
		{
			stepIndex++;
			return RecursiveGetValue(obj, stepProperties, ref stepIndex);
		}
		return obj;
	}

	/// <summary>
	/// S7 ReadValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">读取到的值</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool ReadValues_By_S7(SiemensS7Net connectionIns, List<DAQItem> daqItems, out List<object> values, out string errMsg)
	{
		bool flag = false;
		values = new List<object>();
		errMsg = string.Empty;
		int num = 0;
		try
		{
			foreach (DAQItem daqItem in daqItems)
			{
				OperateResult operateResult = null;
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItem.DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
					operateResult = connectionIns.ReadInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<short>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.UInt16:
					operateResult = connectionIns.ReadUInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<ushort>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int32:
					operateResult = connectionIns.ReadInt32(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<int>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int64:
					operateResult = connectionIns.ReadInt64(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<long>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Single:
					operateResult = connectionIns.ReadFloat(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<float>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Double:
					operateResult = connectionIns.ReadDouble(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<double>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Bool:
					operateResult = connectionIns.ReadBool(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<bool>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.String:
					operateResult = connectionIns.ReadString(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						string content = ((OperateResult<string>)operateResult).Content;
						values.Add(content.Contains("\0") ? content.Remove(content.IndexOf("\0")) : content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.DateTime:
					errMsg = "S7暂不支持数据类型[" + daqItem.DataType + "]";
					values.Add(errMsg);
					break;
				case EnumDataType.Byte:
					operateResult = connectionIns.ReadByte(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<byte>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				default:
					errMsg = "未知的数据类型[" + daqItem.DataType + "]";
					values.Add(errMsg);
					break;
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
				}
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// ModbusTcp ReadValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">读取到的值</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool ReadValues_By_ModbusTcp(ModbusTcpNet connectionIns, List<DAQItem> daqItems, out List<object> values, out string errMsg)
	{
		bool flag = false;
		values = new List<object>();
		errMsg = string.Empty;
		int num = 0;
		try
		{
			foreach (DAQItem daqItem in daqItems)
			{
				OperateResult operateResult = null;
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItem.DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
					operateResult = connectionIns.ReadInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<short>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.UInt16:
					operateResult = connectionIns.ReadUInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<ushort>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int32:
					operateResult = connectionIns.ReadInt32(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<int>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int64:
					operateResult = connectionIns.ReadInt64(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<long>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Single:
					operateResult = connectionIns.ReadFloat(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<float>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Double:
					operateResult = connectionIns.ReadDouble(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<double>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Bool:
					operateResult = connectionIns.ReadBool(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<bool>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.String:
					operateResult = connectionIns.ReadString(daqItem.Address, ushort.Parse(daqItem.Length.ToString()));
					if (operateResult.IsSuccess)
					{
						string content = ((OperateResult<string>)operateResult).Content;
						values.Add(content.Contains("\0") ? content.Remove(content.IndexOf("\0")) : content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.DateTime:
				case EnumDataType.Byte:
					values.Add("ModbusTcp暂不支持数据类型[" + daqItem.DataType + "]");
					break;
				default:
					values.Add("未知的数据类型[" + daqItem.DataType + "]");
					break;
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
				}
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// ModbusRtu ReadValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">读取到的值</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool ReadValues_By_ModbusRtu(ModbusRtu connectionIns, List<DAQItem> daqItems, out List<object> values, out string errMsg)
	{
		bool flag = false;
		values = new List<object>();
		errMsg = string.Empty;
		int num = 0;
		try
		{
			foreach (DAQItem daqItem in daqItems)
			{
				OperateResult operateResult = null;
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItem.DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
					operateResult = connectionIns.ReadInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<short>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.UInt16:
					operateResult = connectionIns.ReadUInt16(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<ushort>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int32:
					operateResult = connectionIns.ReadInt32(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<int>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Int64:
					operateResult = connectionIns.ReadInt64(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<long>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Single:
					operateResult = connectionIns.ReadFloat(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<float>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Double:
					operateResult = connectionIns.ReadDouble(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<double>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.Bool:
					operateResult = connectionIns.ReadBool(daqItem.Address);
					if (operateResult.IsSuccess)
					{
						values.Add(((OperateResult<bool>)operateResult).Content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.String:
					operateResult = connectionIns.ReadString(daqItem.Address, ushort.Parse(daqItem.Length.ToString()));
					if (operateResult.IsSuccess)
					{
						string content = ((OperateResult<string>)operateResult).Content;
						values.Add(content.Contains("\0") ? content.Remove(content.IndexOf("\0")) : content);
					}
					else
					{
						values.Add(operateResult.Message);
					}
					break;
				case EnumDataType.DateTime:
				case EnumDataType.Byte:
					values.Add("ModbusRtu暂不支持数据类型[" + daqItem.DataType + "]");
					break;
				default:
					values.Add("未知的数据类型[" + daqItem.DataType + "]");
					break;
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
				}
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// OPCUA WriteValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="nodeIds">NodeIds</param>
	/// <param name="values">写入的内容</param>
	/// <param name="brand">设备品牌</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool WriteValues_By_OPCUA(OpcUaClient connectionIns, List<string> nodeIds, List<object> values, EnumBrand brand, out string errMsg)
	{
		bool flag = false;
		errMsg = string.Empty;
		try
		{
			switch (brand)
			{
			case EnumBrand.Other:
			case EnumBrand.SIEMENS:
			{
				List<string> list = new List<string>();
				List<object> list2 = new List<object>();
				for (int i = 0; i < nodeIds.Count; i++)
				{
					if (typeof(ICollection).IsAssignableFrom(values[i].GetType()))
					{
						if (!connectionIns.WriteNode(nodeIds[i], (ICollection)values[i]))
						{
							throw new Exception("向设备写入集合类型的值时失败");
						}
					}
					else
					{
						list.Add(nodeIds[i]);
						list2.Add(values[i]);
					}
				}
				flag = connectionIns.WriteNodes(list.ToArray(), list2.ToArray());
				break;
			}
			case EnumBrand.OMRON:
				flag = StructHelper.WriteValues(connectionIns.Session, nodeIds, values);
				break;
			default:
				throw new Exception($"未知的品牌[{brand}]");
			}
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// S7 WriteValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">写入的内容</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool WriteValues_By_S7(SiemensS7Net connectionIns, List<DAQItem> daqItems, List<object> values, out string errMsg)
	{
		bool flag = false;
		errMsg = string.Empty;
		try
		{
			int num = 0;
			OperateResult operateResult = null;
			for (int i = 0; i < daqItems.Count; i++)
			{
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItems[i].DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
				{
					if (!short.TryParse(values[i].ToString(), out var result5))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result5);
					break;
				}
				case EnumDataType.UInt16:
				{
					if (!ushort.TryParse(values[i].ToString(), out var result2))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result2);
					break;
				}
				case EnumDataType.Int32:
				{
					if (!int.TryParse(values[i].ToString(), out var result6))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result6);
					break;
				}
				case EnumDataType.Int64:
				{
					if (!long.TryParse(values[i].ToString(), out var result8))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result8);
					break;
				}
				case EnumDataType.Single:
				{
					if (!float.TryParse(values[i].ToString(), out var result3))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result3);
					break;
				}
				case EnumDataType.Double:
				{
					if (!double.TryParse(values[i].ToString(), out var result7))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result7);
					break;
				}
				case EnumDataType.Bool:
				{
					if (!bool.TryParse(values[i].ToString(), out var result4))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result4);
					break;
				}
				case EnumDataType.String:
					operateResult = connectionIns.Write(daqItems[i].Address, values[i].ToString());
					break;
				case EnumDataType.DateTime:
					throw new Exception("S7暂不支持数据类型[" + daqItems[i].DataType + "]");
				case EnumDataType.Byte:
				{
					if (!byte.TryParse(values[i].ToString(), out var result))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result);
					break;
				}
				default:
					throw new Exception("未知的数据类型[" + daqItems[i].DataType + "]");
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
					continue;
				}
				throw new Exception($"错误代码：{operateResult.ErrorCode}，错误信息：{operateResult.Message}");
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// ModbusTcp WriteValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">写入的内容</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool WriteValues_By_ModbusTcp(ModbusTcpNet connectionIns, List<DAQItem> daqItems, List<object> values, out string errMsg)
	{
		bool flag = false;
		errMsg = string.Empty;
		try
		{
			int num = 0;
			OperateResult operateResult = null;
			for (int i = 0; i < daqItems.Count; i++)
			{
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItems[i].DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
				{
					if (!short.TryParse(values[i].ToString(), out var result2))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result2);
					break;
				}
				case EnumDataType.UInt16:
				{
					if (!ushort.TryParse(values[i].ToString(), out var result6))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result6);
					break;
				}
				case EnumDataType.Int32:
				{
					if (!int.TryParse(values[i].ToString(), out var result3))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result3);
					break;
				}
				case EnumDataType.Int64:
				{
					if (!long.TryParse(values[i].ToString(), out var result5))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result5);
					break;
				}
				case EnumDataType.Single:
				{
					if (!float.TryParse(values[i].ToString(), out var result7))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result7);
					break;
				}
				case EnumDataType.Double:
				{
					if (!double.TryParse(values[i].ToString(), out var result4))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result4);
					break;
				}
				case EnumDataType.Bool:
				{
					if (!bool.TryParse(values[i].ToString(), out var result))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result);
					break;
				}
				case EnumDataType.String:
					operateResult = connectionIns.Write(daqItems[i].Address, values[i].ToString());
					break;
				case EnumDataType.DateTime:
				case EnumDataType.Byte:
					throw new Exception("ModbusTcp暂不支持数据类型[" + daqItems[i].DataType + "]");
				default:
					throw new Exception("未知的数据类型[" + daqItems[i].DataType + "]");
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
					continue;
				}
				throw new Exception($"错误代码：{operateResult.ErrorCode}，错误信息：{operateResult.Message}");
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// ModbusRtu WriteValue
	/// </summary>
	/// <param name="connectionIns">连接实例</param>
	/// <param name="daqItems">采集项</param>
	/// <param name="values">写入的内容</param>
	/// <param name="errMsg">错误信息</param>
	/// <returns></returns>
	private static bool WriteValues_By_ModbusRtu(ModbusRtu connectionIns, List<DAQItem> daqItems, List<object> values, out string errMsg)
	{
		bool flag = false;
		errMsg = string.Empty;
		try
		{
			int num = 0;
			OperateResult operateResult = null;
			for (int i = 0; i < daqItems.Count; i++)
			{
				switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), daqItems[i].DataType, ignoreCase: true))
				{
				case EnumDataType.Int16:
				{
					if (!short.TryParse(values[i].ToString(), out var result2))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result2);
					break;
				}
				case EnumDataType.UInt16:
				{
					if (!ushort.TryParse(values[i].ToString(), out var result6))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result6);
					break;
				}
				case EnumDataType.Int32:
				{
					if (!int.TryParse(values[i].ToString(), out var result3))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result3);
					break;
				}
				case EnumDataType.Int64:
				{
					if (!long.TryParse(values[i].ToString(), out var result5))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result5);
					break;
				}
				case EnumDataType.Single:
				{
					if (!float.TryParse(values[i].ToString(), out var result7))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result7);
					break;
				}
				case EnumDataType.Double:
				{
					if (!double.TryParse(values[i].ToString(), out var result4))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result4);
					break;
				}
				case EnumDataType.Bool:
				{
					if (!bool.TryParse(values[i].ToString(), out var result))
					{
						throw new Exception($"[{values[i]}]不是一个有效的{daqItems[i].DataType}值");
					}
					operateResult = connectionIns.Write(daqItems[i].Address, result);
					break;
				}
				case EnumDataType.String:
					operateResult = connectionIns.Write(daqItems[i].Address, values[i].ToString());
					break;
				case EnumDataType.DateTime:
				case EnumDataType.Byte:
					throw new Exception("ModbusRtu暂不支持数据类型[" + daqItems[i].DataType + "]");
				default:
					throw new Exception("未知的数据类型[" + daqItems[i].DataType + "]");
				}
				if (operateResult != null && operateResult.IsSuccess)
				{
					num++;
					continue;
				}
				throw new Exception($"错误代码：{operateResult.ErrorCode}，错误信息：{operateResult.Message}");
			}
			flag = num == daqItems.Count;
		}
		catch (Exception ex)
		{
			flag = false;
			errMsg = ex.Message;
		}
		return flag;
	}

	/// <summary>
	/// 执行任务
	/// </summary>
	/// <param name="station">站点</param>
	/// <param name="task">任务</param>
	/// <param name="connectionPool">连接池</param>
	/// <param name="devices">设备列表</param>
	/// <param name="socketData">接收到的SocketServer数据</param>
	/// <param name="ignoreTrigger">是否忽略触发条件</param>
	internal static void ExecuteTask(Station station, DAQTask task, List<Connection> connectionPool, List<Device> devices, byte[] socketData = null, bool ignoreTrigger = false)
	{
		string errMsg = string.Empty;
		switch (task.TriggerMode)
		{
		case EnumTaskTriggerMode.Loop:
		case EnumTaskTriggerMode.SocketListen:
		{
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();
			bool flag = false;
			List<object> structInsBuffer = new List<object>();
			List<object> values = null;
			try
			{
				if (ignoreTrigger || task.TriggerMode == EnumTaskTriggerMode.SocketListen)
				{
					flag = true;
				}
				else
				{
					bool flag2 = false;
					int num = 0;
					foreach (IGrouping<Guid, TaskCondition> conditionGroup in from t in task.Conditions
						group t by t.DAQItem.DeviceId)
					{
						Connection connection = connectionPool.FirstOrDefault((Connection t) => t.DeviceId == conditionGroup.Key);
						Device device = devices.FirstOrDefault((Device t) => t.Id == conditionGroup.Key);
						if (ReadValues(connection.ConnectionIns, device, conditionGroup.Select((TaskCondition t) => t.DAQItem).ToList(), out values, out errMsg, structInsBuffer))
						{
							int num2 = 0;
							foreach (TaskCondition item in conditionGroup)
							{
								if (IsConditionSuccessful(item, values[num2++]))
								{
									if ((EnumMultiConditionStrategy)Enum.Parse(typeof(EnumMultiConditionStrategy), task.MultiConditionStrategy, ignoreCase: true) == EnumMultiConditionStrategy.OR)
									{
										flag = true;
										break;
									}
									num++;
								}
								else if ((EnumMultiConditionStrategy)Enum.Parse(typeof(EnumMultiConditionStrategy), task.MultiConditionStrategy, ignoreCase: true) == EnumMultiConditionStrategy.AND)
								{
									flag2 = true;
									break;
								}
							}
							if (flag || flag2)
							{
								break;
							}
							continue;
						}
						throw new Exception(errMsg);
					}
					if (!flag && num == task.Conditions.Count)
					{
						flag = true;
					}
				}
			}
			catch
			{
				break;
			}
			if (Flag_Sick)
			{
				flag = false;
			}
			if (!flag)
			{
				break;
			}
			int logId = -1;
			try
			{
				if (task.NeedLog)
				{
					logId = AddLogProcess(station.Id, station.Name, task.Id, task.Name);
					AddLogProcessDetail(logId, "触发任务[" + task.Name + "]");
				}
				DAQArg dAQArg = new DAQArg(station, task, task.NeedLog, logId);
				if (task.Params.Count > 0)
				{
					if (task.NeedLog)
					{
						AddLogProcessDetail(logId, "开始读取参数");
					}
					Dictionary<string, object> dictionary = new Dictionary<string, object>();
					foreach (TaskParam item2 in task.Params.Where((TaskParam t) => t.IsConst))
					{
						dictionary.Add(item2.DAQItem.Identifier, item2.Const);
						dAQArg.Values.Add(item2.DAQItem.Identifier, item2.Const);
					}
					if (task.NeedLog && dictionary.Count > 0)
					{
						AddLogProcessDetail(logId, "常量参数获取成功：" + JsonConvert.SerializeObject(dictionary));
					}
					foreach (IGrouping<Guid, TaskParam> paramGroup in from t in task.Params
						where !t.IsConst
						group t by t.DAQItem.DeviceId)
					{
						Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
						Connection connection2 = connectionPool.FirstOrDefault((Connection t) => t.DeviceId == paramGroup.Key);
						Device device2 = devices.FirstOrDefault((Device t) => t.Id == paramGroup.Key);
						foreach (TaskParam item3 in paramGroup.Where((TaskParam t) => t.SingleRead))
						{
							if (ReadValues(connection2.ConnectionIns, device2, new List<DAQItem> { item3.DAQItem }, out values, out errMsg, structInsBuffer))
							{
								dictionary2.Add(item3.DAQItem.Identifier, values[0]);
								dAQArg.Values.Add(item3.DAQItem.Identifier, values[0]);
								continue;
							}
							dictionary2.Add(item3.DAQItem.Identifier, item3.DefaultValue);
							dAQArg.Values.Add(item3.DAQItem.Identifier, item3.DefaultValue);
							if (task.NeedLog)
							{
								AddLogProcessDetail(logId, "设备[" + device2.Name + "]的参数[" + item3.DAQItem.Identifier + "]单独读取失败：" + errMsg + "\r使用默认值[" + item3.DefaultValue + "]作为参数的值");
							}
						}
						if (!paramGroup.Any((TaskParam t) => !t.SingleRead))
						{
							continue;
						}
						if (ReadValues(connection2.ConnectionIns, device2, (from t in paramGroup
							where !t.SingleRead
							select t.DAQItem).ToList(), out values, out errMsg, structInsBuffer))
						{
							int num3 = 0;
							foreach (TaskParam item4 in paramGroup)
							{
								dictionary2.Add(item4.DAQItem.Identifier, values[num3]);
								dAQArg.Values.Add(item4.DAQItem.Identifier, values[num3]);
								num3++;
							}
							if (task.NeedLog)
							{
								AddLogProcessDetail(logId, "设备[" + device2.Name + "]参数读取成功：" + JsonConvert.SerializeObject(dictionary2));
							}
							continue;
						}
						if (task.NeedLog)
						{
							AddLogProcessDetail(logId, "设备[" + device2.Name + "]参数读取失败：" + errMsg);
						}
						return;
					}
				}
				if (task.TriggerMode == EnumTaskTriggerMode.SocketListen && task.SocketMsgAsParam)
				{
					dAQArg.Values.Add(task.SocketMsgIdentifier, socketData);
					string text = "IP";
					string text2 = "Port";
					if (dAQArg.Values.ContainsKey(text))
					{
						AddLogProcessDetail(logId, "传递SocketServer消息作为参数时，arg.Values的Key值[" + text + "]将被平台占用。");
					}
					else
					{
						dAQArg.Values.Add(text, task.SocketServer.IP);
					}
					if (dAQArg.Values.ContainsKey(text2))
					{
						AddLogProcessDetail(logId, "传递SocketServer消息作为参数时，arg.Values的Key值[" + text2 + "]将被平台占用。");
					}
					else
					{
						dAQArg.Values.Add(text2, task.SocketServer.Port);
					}
					if (task.NeedLog)
					{
						AddLogProcessDetail(logId, "监听到SocketServer消息 \rHex：" + socketData.ToHexStr() + "\rEncoding：" + socketData.ToEncodingStr());
					}
				}
				DAQResult dAQResult = null;
				if (!string.IsNullOrEmpty(task.MethodName))
				{
					object obj3 = null;
					MethodInfo methodInfo = null;
					if (METHOD_POOL.ContainsKey(task.Namespace) && METHOD_POOL[task.Namespace].Keys.Any((string t) => t == task.ClassName) && METHOD_POOL[task.Namespace][task.ClassName].Keys.Any((MethodInfo t) => t.Name == task.MethodName))
					{
						methodInfo = METHOD_POOL[task.Namespace][task.ClassName].Keys.FirstOrDefault((MethodInfo t) => t.Name == task.MethodName);
						obj3 = METHOD_POOL[task.Namespace][task.ClassName][methodInfo];
					}
					else
					{
						Assembly assembly = Assembly.LoadFrom(Application.ExecutablePath);
						Type[] types = assembly.GetTypes();
						Type[] array = types;
						foreach (Type type in array)
						{
							if (!typeof(IIdentity).IsAssignableFrom(type))
							{
								continue;
							}
							obj3 = Activator.CreateInstance(type);
							MethodInfo[] methods = type.GetMethods();
							if (string.IsNullOrEmpty(task.ClassName) && string.IsNullOrEmpty(task.Namespace))
							{
								methodInfo = methods.FirstOrDefault((MethodInfo t) => t.Name == task.MethodName);
							}
							else if (!string.IsNullOrEmpty(task.ClassName) && string.IsNullOrEmpty(task.Namespace))
							{
								if (!(type.Name == task.ClassName))
								{
									continue;
								}
								methodInfo = methods.FirstOrDefault((MethodInfo t) => t.Name == task.MethodName);
							}
							else if (string.IsNullOrEmpty(task.ClassName) && !string.IsNullOrEmpty(task.Namespace))
							{
								if (!(type.Namespace == task.Namespace))
								{
									continue;
								}
								methodInfo = methods.FirstOrDefault((MethodInfo t) => t.Name == task.MethodName);
							}
							else if (!string.IsNullOrEmpty(task.ClassName) && !string.IsNullOrEmpty(task.Namespace))
							{
								if (!(type.Name == task.ClassName) || !(type.Namespace == task.Namespace))
								{
									continue;
								}
								methodInfo = methods.FirstOrDefault((MethodInfo t) => t.Name == task.MethodName);
							}
							if (!(methodInfo != null))
							{
								continue;
							}
							if (METHOD_POOL.ContainsKey(task.Namespace))
							{
								if (METHOD_POOL[task.Namespace].ContainsKey(task.ClassName))
								{
									METHOD_POOL[task.Namespace][task.ClassName].Add(methodInfo, obj3);
									break;
								}
								METHOD_POOL[task.Namespace].Add(task.ClassName, new Dictionary<MethodInfo, object> { { methodInfo, obj3 } });
							}
							else
							{
								METHOD_POOL.Add(task.Namespace, new Dictionary<string, Dictionary<MethodInfo, object>> { 
								{
									task.ClassName,
									new Dictionary<MethodInfo, object> { { methodInfo, obj3 } }
								} });
							}
							break;
						}
					}
					if (obj3 == null)
					{
						throw new Exception("类实例为null");
					}
					if (methodInfo == null)
					{
						throw new Exception("未找到方法[" + task.MethodName + "]");
					}
					dAQResult = (DAQResult)methodInfo.Invoke(obj3, new object[1] { dAQArg });
					if (dAQResult == null)
					{
						throw new Exception("方法[" + task.MethodName + "]返回结果为null");
					}
					if (task.NeedLog)
					{
						if (dAQResult.Result)
						{
							AddLogProcessDetail(logId, "方法[" + task.MethodName + "]执行成功。\r返回值：" + JsonConvert.SerializeObject(dAQResult.Values));
						}
						else
						{
							AddLogProcessDetail(logId, "方法[" + task.MethodName + "]执行失败:" + dAQResult.ErrMsg);
						}
					}
				}
				if ((!string.IsNullOrEmpty(task.MethodName) && !dAQResult.Result) || (task.Writebacks.Count <= 0 && !task.WritebackSocketMsg))
				{
					break;
				}
				values = new List<object>();
				foreach (IGrouping<Guid, TaskWriteback> writebackGroup in from t in task.Writebacks
					group t by t.DAQItem.DeviceId)
				{
					Dictionary<string, object> dictionary3 = null;
					if (task.NeedLog)
					{
						dictionary3 = new Dictionary<string, object>();
					}
					foreach (TaskWriteback item5 in writebackGroup)
					{
						if (item5.ContentSource.ToUpper() == "Const".ToUpper())
						{
							values.Add(item5.Content);
							if (task.NeedLog)
							{
								dictionary3.Add(item5.DAQItem.Identifier, item5.Content);
							}
						}
						else if (item5.ContentSource.ToUpper() == "Variable".ToUpper())
						{
							if (!dAQResult.Values.ContainsKey(item5.Content.ToString()))
							{
								throw new Exception($"返回值中缺少需要回写设备的关键字[{item5.Content}]");
							}
							values.Add(dAQResult.Values[item5.Content.ToString()]);
							if (task.NeedLog)
							{
								dictionary3.Add(item5.Content.ToString(), dAQResult.Values[item5.Content.ToString()]);
							}
						}
					}
					Connection connection3 = connectionPool.FirstOrDefault((Connection t) => t.DeviceId == writebackGroup.Key);
					Device device3 = devices.FirstOrDefault((Device t) => t.Id == writebackGroup.Key);
					if (task.NeedLog)
					{
						AddLogProcessDetail(logId, "尝试向设备[" + device3.Name + "]写入：" + JsonConvert.SerializeObject(dictionary3));
					}
					if (WriteValues(connection3.ConnectionIns, device3, writebackGroup.Select((TaskWriteback t) => t.DAQItem).ToList(), values, out errMsg))
					{
						if (task.NeedLog)
						{
							AddLogProcessDetail(logId, "设备[" + device3.Name + "]写入成功");
						}
					}
					else if (task.NeedLog)
					{
						AddLogProcessDetail(logId, "设备[" + device3.Name + "]写入失败：" + errMsg);
					}
				}
				if (task.TriggerMode != EnumTaskTriggerMode.SocketListen || !task.WritebackSocketMsg)
				{
					break;
				}
				byte[] array2 = null;
				if (task.SocketMsgWritebackSource.ToUpper() == "Variable".ToUpper() && dAQResult.Values[task.SocketMsgWritebackContent].GetType() == typeof(byte[]))
				{
					array2 = (byte[])dAQResult.Values[task.SocketMsgWritebackContent];
				}
				else
				{
					string text3 = string.Empty;
					if (task.SocketMsgWritebackSource.ToUpper() == "Const".ToUpper())
					{
						text3 = task.SocketMsgWritebackContent;
					}
					else if (task.SocketMsgWritebackSource.ToUpper() == "Variable".ToUpper())
					{
						text3 = dAQResult.Values[task.SocketMsgWritebackContent].ToString();
					}
					if (task.SocketMsgWritebackIsString)
					{
						array2 = Encoding.UTF8.GetBytes(text3);
					}
					else
					{
						if (!text3.IsHex())
						{
							throw new Exception("向SocketServer回写的内容应为byte[]、常规字符串、或十六进制的字符串且以空格分隔。");
						}
						array2 = (from t in text3.Split(' ')
							select Convert.ToByte(t, 16)).ToArray();
					}
				}
				Connection connection4 = connectionPool.FirstOrDefault(delegate(Connection t)
				{
					Guid deviceId = t.DeviceId;
					Guid? socketServerId2 = task.SocketServerId;
					return deviceId == socketServerId2;
				});
				Device device4 = devices.FirstOrDefault(delegate(Device t)
				{
					Guid id = t.Id;
					Guid? socketServerId = task.SocketServerId;
					return id == socketServerId;
				});
				if (task.NeedLog)
				{
					AddLogProcessDetail(logId, "尝试向设备[" + device4.Name + "]发送消息 \rHex：" + array2.ToHexStr() + "\rEncoding：" + array2.ToEncodingStr());
				}
				int num4 = ((TCPClient)connection4.ConnectionIns).NetWork.Client.Send(array2);
				if (num4 == array2.Length)
				{
					if (task.NeedLog)
					{
						AddLogProcessDetail(logId, "发送成功");
					}
				}
				else if (task.NeedLog)
				{
					AddLogProcessDetail(logId, $"发送失败：需要发送的字节数为{array2.Length}，实际发送的字节数为{num4}");
				}
				break;
			}
			catch (Exception ex)
			{
				if (task.NeedLog)
				{
					AddLogProcessDetail(logId, "Exception：" + ex.Message + "\r\nInnerException：" + ex.InnerException?.Message);
				}
				break;
			}
			finally
			{
				stopwatch.Stop();
				if (task.NeedLog)
				{
					AddLogProcessDetail(logId, "结束任务[" + task.Name + "]");
					FinishLogProcess(logId, stopwatch.Elapsed.TotalSeconds);
				}
			}
		}
		case EnumTaskTriggerMode.Subscribe:
			try
			{
				break;
			}
			catch
			{
				break;
			}
		default:
			throw new Exception($"[任务-{task.Name}]使用了未知的触发方式[{task.TriggerMode}]");
		}
	}

	/// <summary>
	/// 判断任务条件是否满足
	/// </summary>
	/// <param name="condition">TaskCondition</param>
	/// <param name="readValue">读取到的值</param>
	/// <returns></returns>
	private static bool IsConditionSuccessful(TaskCondition condition, object readValue)
	{
		switch ((EnumDataType)Enum.Parse(typeof(EnumDataType), condition.DAQItem.DataType, ignoreCase: true))
		{
		case EnumDataType.Int16:
			return condition.Operator switch
			{
				"=" => Convert.ToInt16(readValue) == Convert.ToInt16(condition.Value), 
				"!=" => Convert.ToInt16(readValue) != Convert.ToInt16(condition.Value), 
				">=" => Convert.ToInt16(readValue) >= Convert.ToInt16(condition.Value), 
				">" => Convert.ToInt16(readValue) > Convert.ToInt16(condition.Value), 
				"<=" => Convert.ToInt16(readValue) <= Convert.ToInt16(condition.Value), 
				"<" => Convert.ToInt16(readValue) < Convert.ToInt16(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.UInt16:
			return condition.Operator switch
			{
				"=" => Convert.ToUInt16(readValue) == Convert.ToUInt16(condition.Value), 
				"!=" => Convert.ToUInt16(readValue) != Convert.ToUInt16(condition.Value), 
				">=" => Convert.ToUInt16(readValue) >= Convert.ToUInt16(condition.Value), 
				">" => Convert.ToUInt16(readValue) > Convert.ToUInt16(condition.Value), 
				"<=" => Convert.ToUInt16(readValue) <= Convert.ToUInt16(condition.Value), 
				"<" => Convert.ToUInt16(readValue) < Convert.ToUInt16(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Int32:
			return condition.Operator switch
			{
				"=" => Convert.ToInt32(readValue) == Convert.ToInt32(condition.Value), 
				"!=" => Convert.ToInt32(readValue) != Convert.ToInt32(condition.Value), 
				">=" => Convert.ToInt32(readValue) >= Convert.ToInt32(condition.Value), 
				">" => Convert.ToInt32(readValue) > Convert.ToInt32(condition.Value), 
				"<=" => Convert.ToInt32(readValue) <= Convert.ToInt32(condition.Value), 
				"<" => Convert.ToInt32(readValue) < Convert.ToInt32(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Int64:
			return condition.Operator switch
			{
				"=" => Convert.ToInt64(readValue) == Convert.ToInt64(condition.Value), 
				"!=" => Convert.ToInt64(readValue) != Convert.ToInt64(condition.Value), 
				">=" => Convert.ToInt64(readValue) >= Convert.ToInt64(condition.Value), 
				">" => Convert.ToInt64(readValue) > Convert.ToInt64(condition.Value), 
				"<=" => Convert.ToInt64(readValue) <= Convert.ToInt64(condition.Value), 
				"<" => Convert.ToInt64(readValue) < Convert.ToInt64(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Single:
			return condition.Operator switch
			{
				"=" => Convert.ToSingle(readValue) == Convert.ToSingle(condition.Value), 
				"!=" => Convert.ToSingle(readValue) != Convert.ToSingle(condition.Value), 
				">=" => Convert.ToSingle(readValue) >= Convert.ToSingle(condition.Value), 
				">" => Convert.ToSingle(readValue) > Convert.ToSingle(condition.Value), 
				"<=" => Convert.ToSingle(readValue) <= Convert.ToSingle(condition.Value), 
				"<" => Convert.ToSingle(readValue) < Convert.ToSingle(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Double:
			return condition.Operator switch
			{
				"=" => Convert.ToDouble(readValue) == Convert.ToDouble(condition.Value), 
				"!=" => Convert.ToDouble(readValue) != Convert.ToDouble(condition.Value), 
				">=" => Convert.ToDouble(readValue) >= Convert.ToDouble(condition.Value), 
				">" => Convert.ToDouble(readValue) > Convert.ToDouble(condition.Value), 
				"<=" => Convert.ToDouble(readValue) <= Convert.ToDouble(condition.Value), 
				"<" => Convert.ToDouble(readValue) < Convert.ToDouble(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Bool:
			switch (condition.Operator)
			{
			case "=":
				return Convert.ToBoolean(readValue) == Convert.ToBoolean(condition.Value);
			case "!=":
				return Convert.ToBoolean(readValue) != Convert.ToBoolean(condition.Value);
			case ">=":
			case ">":
			case "<=":
			case "<":
				throw new Exception("数据类型[" + condition.DAQItem.DataType + "]不允许使用条件运算符[" + condition.Operator + "]");
			default:
				throw new Exception("未知的触发条件运算符[" + condition.Operator + "]");
			}
		case EnumDataType.String:
			switch (condition.Operator)
			{
			case "=":
				return readValue.ToString() == condition.Value.ToString();
			case "!=":
				return readValue.ToString() != condition.Value.ToString();
			case ">=":
			case ">":
			case "<=":
			case "<":
				throw new Exception("数据类型[" + condition.DAQItem.DataType + "]不允许使用条件运算符[" + condition.Operator + "]");
			default:
				throw new Exception("未知的触发条件运算符[" + condition.Operator + "]");
			}
		case EnumDataType.DateTime:
			return condition.Operator switch
			{
				"=" => Convert.ToDateTime(readValue) == Convert.ToDateTime(condition.Value), 
				"!=" => Convert.ToDateTime(readValue) != Convert.ToDateTime(condition.Value), 
				">=" => Convert.ToDateTime(readValue) >= Convert.ToDateTime(condition.Value), 
				">" => Convert.ToDateTime(readValue) > Convert.ToDateTime(condition.Value), 
				"<=" => Convert.ToDateTime(readValue) <= Convert.ToDateTime(condition.Value), 
				"<" => Convert.ToDateTime(readValue) < Convert.ToDateTime(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		case EnumDataType.Byte:
			return condition.Operator switch
			{
				"=" => Convert.ToByte(readValue) == Convert.ToByte(condition.Value), 
				"!=" => Convert.ToByte(readValue) != Convert.ToByte(condition.Value), 
				">=" => Convert.ToByte(readValue) >= Convert.ToByte(condition.Value), 
				">" => Convert.ToByte(readValue) > Convert.ToByte(condition.Value), 
				"<=" => Convert.ToByte(readValue) <= Convert.ToByte(condition.Value), 
				"<" => Convert.ToByte(readValue) < Convert.ToByte(condition.Value), 
				_ => throw new Exception("未知的触发条件运算符[" + condition.Operator + "]"), 
			};
		default:
			throw new Exception($"任务条件[{condition.Id}]中使用了未知的数据类型[{condition.DAQItem.DataType}]");
		}
	}

	/// <summary>
	/// 获取SQLite连接字符串
	/// </summary>
	/// <param name="sqlLiteFilePath">SQLite文件路径</param>
	/// <returns></returns>
	private static string GetConnectionString(string sqlLiteFilePath)
	{
		if (!File.Exists(sqlLiteFilePath))
		{
			throw new Exception("文件" + sqlLiteFilePath + "不存在");
		}
		SQLiteConnectionStringBuilder sQLiteConnectionStringBuilder = new SQLiteConnectionStringBuilder
		{
			DataSource = sqlLiteFilePath,
			Version = 3,
			Pooling = true,
			ReadOnly = false,
			SyncMode = SynchronizationModes.Off
		};
		return sQLiteConnectionStringBuilder.ConnectionString;
	}

	/// <summary>
	/// 添加日志记录
	/// </summary>
	/// <param name="stationId"></param>
	/// <param name="stationName"></param>
	/// <param name="taskId"></param>
	/// <param name="taskName"></param> 
	/// <returns></returns>
	internal static int AddLogProcess(Guid stationId, string stationName, Guid taskId, string taskName)
	{
		int result = -1;
		try
		{
			string text = " insert into process (station_id,station_name,task_id,task_name,create_time) \r\n                                values \r\n                                (@Stationid,@StationName,@TaskId,@TaskName,@CreateTime);";
			switch (LogSourceType)
			{
			case 1:
			{
				text += " select last_insert_rowid() from process;";
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[5]
				{
					new SQLiteParameter("@StationId", DbType.String)
					{
						Value = stationId
					},
					new SQLiteParameter("@StationName", DbType.String)
					{
						Value = stationName
					},
					new SQLiteParameter("@TaskId", DbType.String)
					{
						Value = taskId
					},
					new SQLiteParameter("@TaskName", DbType.String)
					{
						Value = taskName
					},
					new SQLiteParameter("@CreateTime", DbType.DateTime)
					{
						Value = DateTime.Now
					}
				};
				lock (LOCK_WRITE_PROCESS)
				{
					result = Convert.ToInt32(SQLiteHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, text, commandParameters2));
				}
				break;
			}
			case 2:
			{
				text += " SELECT LAST_INSERT_ID();";
				MySqlParameter[] commandParameters = new MySqlParameter[5]
				{
					new MySqlParameter("@StationId", MySqlDbType.Guid)
					{
						Value = stationId
					},
					new MySqlParameter("@StationName", MySqlDbType.VarChar)
					{
						Value = stationName
					},
					new MySqlParameter("@TaskId", MySqlDbType.Guid)
					{
						Value = taskId
					},
					new MySqlParameter("@TaskName", MySqlDbType.VarChar)
					{
						Value = taskName
					},
					new MySqlParameter("@CreateTime", MySqlDbType.DateTime)
					{
						Value = DateTime.Now
					}
				};
				result = Convert.ToInt32(MySQLHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, text, commandParameters));
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 添加日志记录
	/// </summary>
	/// <param name="stationName"></param> 
	/// <param name="taskName"></param> 
	/// <returns></returns>
	internal static int AddLogProcess(string stationName, string taskName)
	{
		int result = -1;
		try
		{
			string text = " insert into process (station_name,task_name,create_time) \r\n                                values \r\n                                (@StationName,@TaskName,@CreateTime);";
			switch (LogSourceType)
			{
			case 1:
			{
				text += " select last_insert_rowid() from process;";
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[3]
				{
					new SQLiteParameter("@StationName", DbType.String)
					{
						Value = stationName
					},
					new SQLiteParameter("@TaskName", DbType.String)
					{
						Value = taskName
					},
					new SQLiteParameter("@CreateTime", DbType.DateTime)
					{
						Value = DateTime.Now
					}
				};
				lock (LOCK_WRITE_PROCESS)
				{
					result = Convert.ToInt32(SQLiteHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, text, commandParameters2));
				}
				break;
			}
			case 2:
			{
				text += " SELECT LAST_INSERT_ID();";
				MySqlParameter[] commandParameters = new MySqlParameter[3]
				{
					new MySqlParameter("@StationName", MySqlDbType.VarChar)
					{
						Value = stationName
					},
					new MySqlParameter("@TaskName", MySqlDbType.VarChar)
					{
						Value = taskName
					},
					new MySqlParameter("@CreateTime", MySqlDbType.DateTime)
					{
						Value = DateTime.Now
					}
				};
				result = Convert.ToInt32(MySQLHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, text, commandParameters));
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 添加日志明细
	/// </summary>
	/// <param name="logId"></param>
	/// <param name="content"></param> 
	internal static void AddLogProcessDetail(int logId, string content)
	{
		try
		{
			string text = "insert into process_detail (process_id,create_time,content) values (@ProcessId,@CreateTime,@Content)";
			switch (LogSourceType)
			{
			case 1:
			{
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[3]
				{
					new SQLiteParameter("@ProcessId", DbType.Int64)
					{
						Value = logId
					},
					new SQLiteParameter("@CreateTime", DbType.DateTime)
					{
						Value = DateTime.Now
					},
					new SQLiteParameter("@Content", DbType.String)
					{
						Value = content
					}
				};
				lock (LOCK_WRITE_PROCESSDETAIL)
				{
					SQLiteHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters2);
					break;
				}
			}
			case 2:
			{
				MySqlParameter[] commandParameters = new MySqlParameter[3]
				{
					new MySqlParameter("@ProcessId", MySqlDbType.Int64)
					{
						Value = logId
					},
					new MySqlParameter("@CreateTime", MySqlDbType.DateTime)
					{
						Value = DateTime.Now
					},
					new MySqlParameter("@Content", MySqlDbType.Text)
					{
						Value = content
					}
				};
				MySQLHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters);
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
	}

	/// <summary>
	/// 日志完结
	/// </summary>
	/// <param name="logId"></param>
	/// <param name="duration">任务耗时(s)</param>
	internal static void FinishLogProcess(int logId, double duration)
	{
		try
		{
			string text = " update process set duration=@Duration where id=@Id";
			switch (LogSourceType)
			{
			case 1:
			{
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[2]
				{
					new SQLiteParameter("@Id", DbType.Int64)
					{
						Value = logId
					},
					new SQLiteParameter("@Duration", DbType.Decimal)
					{
						Value = duration
					}
				};
				lock (LOCK_WRITE_PROCESS)
				{
					SQLiteHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters2);
					break;
				}
			}
			case 2:
			{
				MySqlParameter[] commandParameters = new MySqlParameter[2]
				{
					new MySqlParameter("@Id", MySqlDbType.Int64)
					{
						Value = logId
					},
					new MySqlParameter("@Duration", MySqlDbType.Decimal)
					{
						Value = duration
					}
				};
				MySQLHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters);
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
	}

	/// <summary>
	/// 日志完结
	/// </summary>
	/// <param name="logId"></param>
	internal static void FinishLogProcess(int logId)
	{
		try
		{
			switch (LogSourceType)
			{
			case 1:
				lock (LOCK_WRITE_PROCESS)
				{
					string commandText = "select create_time from process where id=@Id";
					SQLiteParameter[] commandParameters2 = new SQLiteParameter[1]
					{
						new SQLiteParameter("@Id", DbType.Int64)
						{
							Value = logId
						}
					};
					DateTime dateTime2 = Convert.ToDateTime(SQLiteHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, commandText, commandParameters2));
					double totalSeconds2 = (DateTime.Now - dateTime2).TotalSeconds;
					commandText = "update process set duration=@Duration where id=@Id";
					commandParameters2 = new SQLiteParameter[2]
					{
						new SQLiteParameter("@Id", DbType.Int64)
						{
							Value = logId
						},
						new SQLiteParameter("@Duration", DbType.Decimal)
						{
							Value = totalSeconds2
						}
					};
					SQLiteHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, commandText, commandParameters2);
					break;
				}
			case 2:
			{
				string cmdText = "select create_time from process where id=@Id";
				MySqlParameter[] commandParameters = new MySqlParameter[1]
				{
					new MySqlParameter("@Id", MySqlDbType.Int64)
					{
						Value = logId
					}
				};
				DateTime dateTime = Convert.ToDateTime(MySQLHelper.ExecuteScalar(LOG_CONNSTR, CommandType.Text, cmdText, commandParameters));
				double totalSeconds = (DateTime.Now - dateTime).TotalSeconds;
				cmdText = "update process set duration=@Duration where id=@Id";
				commandParameters = new MySqlParameter[2]
				{
					new MySqlParameter("@Id", MySqlDbType.Int64)
					{
						Value = logId
					},
					new MySqlParameter("@Duration", MySqlDbType.Decimal)
					{
						Value = totalSeconds
					}
				};
				MySQLHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, cmdText, commandParameters);
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
	}

	/// <summary>
	/// 查询日志记录
	/// </summary>
	/// <param name="stationId">工站Id</param>
	/// <param name="taskId">任务Id</param>
	/// <param name="startTime">时间区间起始</param>
	/// <param name="endTime">时间区间截止</param>
	/// <param name="maxCount">查询数量限制</param>
	/// <param name="filterDuration">是否过滤查询</param>
	/// <param name="duration">过滤条件-执行时长</param>
	/// <returns></returns>
	internal static DataTable QueryLogProcesses(Guid? stationId, Guid? taskId, DateTime startTime, DateTime endTime, int maxCount, bool filterDuration, decimal duration)
	{
		DataTable result = null;
		try
		{
			string text = " select id,station_id,station_name,task_id,task_name,create_time,duration,already_read \r\n                                from process where create_time>=@StartTime and create_time<=@EndTime";
			switch (LogSourceType)
			{
			case 1:
			{
				List<SQLiteParameter> list2 = new List<SQLiteParameter>
				{
					new SQLiteParameter("@StartTime", DbType.DateTime)
					{
						Value = startTime
					},
					new SQLiteParameter("@EndTime", DbType.DateTime)
					{
						Value = endTime
					},
					new SQLiteParameter("@Limit", DbType.Int32)
					{
						Value = maxCount
					}
				};
				if (stationId.HasValue && stationId != default(Guid))
				{
					text += " and station_id=@StationId";
					list2.Add(new SQLiteParameter("@StationId", DbType.String)
					{
						Value = stationId
					});
				}
				if (taskId.HasValue && taskId != default(Guid))
				{
					text += " and task_id=@TaskId";
					list2.Add(new SQLiteParameter("@TaskId", DbType.String)
					{
						Value = taskId
					});
				}
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list2.Add(new SQLiteParameter("@Duration", DbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by id desc limit 0,@Limit";
				result = SQLiteHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list2.ToArray()).Tables[0];
				break;
			}
			case 2:
			{
				List<MySqlParameter> list = new List<MySqlParameter>
				{
					new MySqlParameter("@StartTime", MySqlDbType.DateTime)
					{
						Value = startTime
					},
					new MySqlParameter("@EndTime", MySqlDbType.DateTime)
					{
						Value = endTime
					},
					new MySqlParameter("@Limit", MySqlDbType.Int32)
					{
						Value = maxCount
					}
				};
				if (stationId.HasValue && stationId != default(Guid))
				{
					text += " and station_id=@StationId";
					list.Add(new MySqlParameter("@StationId", MySqlDbType.Guid)
					{
						Value = stationId
					});
				}
				if (taskId.HasValue && taskId != default(Guid))
				{
					text += " and task_id=@TaskId";
					list.Add(new MySqlParameter("@TaskId", MySqlDbType.Guid)
					{
						Value = taskId
					});
				}
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list.Add(new MySqlParameter("@Duration", MySqlDbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by id desc limit 0,@Limit";
				result = MySQLHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list.ToArray()).Tables[0];
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 查询日志记录（根据工站和任务的名称进行查询）
	/// </summary>
	/// <param name="stationName">工站名称</param>
	/// <param name="taskName">任务名称</param>
	/// <param name="startTime">时间区间起始</param>
	/// <param name="endTime">时间区间截止</param>
	/// <param name="maxCount">查询数量限制</param>
	/// <param name="filterDuration">是否过滤查询</param>
	/// <param name="duration">过滤条件-执行时长</param>
	/// <returns></returns>
	internal static DataTable QueryLogProcesses(string stationName, string taskName, DateTime startTime, DateTime endTime, int maxCount, bool filterDuration, decimal duration)
	{
		DataTable result = null;
		try
		{
			string text = " select id,station_id,station_name,task_id,task_name,create_time,duration,already_read \r\n                                from process where create_time>=@StartTime and create_time<=@EndTime";
			switch (LogSourceType)
			{
			case 1:
			{
				List<SQLiteParameter> list2 = new List<SQLiteParameter>
				{
					new SQLiteParameter("@StartTime", DbType.DateTime)
					{
						Value = startTime
					},
					new SQLiteParameter("@EndTime", DbType.DateTime)
					{
						Value = endTime
					},
					new SQLiteParameter("@Limit", DbType.Int32)
					{
						Value = maxCount
					}
				};
				if (!string.IsNullOrEmpty(stationName))
				{
					text += " and station_name=@StationName";
					list2.Add(new SQLiteParameter("@StationName", DbType.String)
					{
						Value = stationName
					});
				}
				if (!string.IsNullOrEmpty(taskName))
				{
					text += " and task_name=@TaskName";
					list2.Add(new SQLiteParameter("@TaskName", DbType.String)
					{
						Value = taskName
					});
				}
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list2.Add(new SQLiteParameter("@Duration", DbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by id desc limit 0,@Limit";
				result = SQLiteHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list2.ToArray()).Tables[0];
				break;
			}
			case 2:
			{
				List<MySqlParameter> list = new List<MySqlParameter>
				{
					new MySqlParameter("@StartTime", MySqlDbType.DateTime)
					{
						Value = startTime
					},
					new MySqlParameter("@EndTime", MySqlDbType.DateTime)
					{
						Value = endTime
					},
					new MySqlParameter("@Limit", MySqlDbType.Int32)
					{
						Value = maxCount
					}
				};
				if (!string.IsNullOrEmpty(stationName))
				{
					text += " and station_name=@StationName";
					list.Add(new MySqlParameter("@StationName", MySqlDbType.VarChar)
					{
						Value = stationName
					});
				}
				if (!string.IsNullOrEmpty(taskName))
				{
					text += " and task_name=@TaskName";
					list.Add(new MySqlParameter("@TaskName", MySqlDbType.VarChar)
					{
						Value = taskName
					});
				}
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list.Add(new MySqlParameter("@Duration", MySqlDbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by id desc limit 0,@Limit";
				result = MySQLHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list.ToArray()).Tables[0];
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 查询日志记录（根据明细中的内容进行模糊查询）
	/// </summary>
	/// <param name="fuzzyContent">需要模糊查询的日志明细中的内容</param>
	/// <param name="maxCount">查询数量限制</param>
	/// <param name="filterDuration">是否过滤查询</param>
	/// <param name="duration">过滤条件-执行时长</param>
	/// <returns></returns>
	internal static DataTable QueryLogProcesses(string fuzzyContent, int maxCount, bool filterDuration, decimal duration)
	{
		DataTable result = null;
		try
		{
			if (!fuzzyContent.StartsWith("%"))
			{
				fuzzyContent = "%" + fuzzyContent;
			}
			if (!fuzzyContent.EndsWith("%"))
			{
				fuzzyContent += "%";
			}
			string text = " select distinct p.id,p.station_id,p.station_name,p.task_id,p.task_name,p.create_time,p.duration,p.already_read \r\n                                from process p\r\n                                inner join process_detail pd on pd.process_id = p.id\r\n                                where pd.content like @FuzzyContent";
			switch (LogSourceType)
			{
			case 1:
			{
				List<SQLiteParameter> list2 = new List<SQLiteParameter>
				{
					new SQLiteParameter("@FuzzyContent", DbType.String)
					{
						Value = fuzzyContent
					},
					new SQLiteParameter("@Limit", DbType.Int32)
					{
						Value = maxCount
					}
				};
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list2.Add(new SQLiteParameter("@Duration", DbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by p.id desc limit 0,@Limit";
				result = SQLiteHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list2.ToArray()).Tables[0];
				break;
			}
			case 2:
			{
				List<MySqlParameter> list = new List<MySqlParameter>
				{
					new MySqlParameter("@FuzzyContent", MySqlDbType.String)
					{
						Value = fuzzyContent
					},
					new MySqlParameter("@Limit", MySqlDbType.Int32)
					{
						Value = maxCount
					}
				};
				if (filterDuration)
				{
					text += " and duration>=@Duration";
					list.Add(new MySqlParameter("@Duration", MySqlDbType.Decimal)
					{
						Value = duration
					});
				}
				text += " order by p.id desc limit 0,@Limit";
				result = MySQLHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, list.ToArray()).Tables[0];
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 查询日志明细
	/// </summary>
	/// <param name="logId">任务Id</param>
	/// <param name="errMsg">查询失败时返回错误信息</param>
	/// <returns></returns>
	internal static DataTable QueryLogDetails(int logId, out string errMsg)
	{
		errMsg = string.Empty;
		DataTable result = null;
		try
		{
			string text = "select id,process_id,create_time,content from process_detail where process_id=@LogId order by id desc";
			switch (LogSourceType)
			{
			case 1:
			{
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[1]
				{
					new SQLiteParameter("@LogId", DbType.Int64)
					{
						Value = logId
					}
				};
				result = SQLiteHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, commandParameters2).Tables[0];
				break;
			}
			case 2:
			{
				MySqlParameter[] commandParameters = new MySqlParameter[1]
				{
					new MySqlParameter("@LogId", MySqlDbType.Int64)
					{
						Value = logId
					}
				};
				result = MySQLHelper.ExecuteDataset(LOG_CONNSTR, CommandType.Text, text, commandParameters).Tables[0];
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			errMsg = ex.Message;
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 更新已读
	/// </summary>
	/// <param name="logId"></param>
	/// <returns></returns>
	internal static bool AlreadyRead(int logId)
	{
		bool result = false;
		try
		{
			string text = "update process set already_read=1 where id=@Id";
			switch (LogSourceType)
			{
			case 1:
			{
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[1]
				{
					new SQLiteParameter("@Id", DbType.Int64)
					{
						Value = logId
					}
				};
				lock (LOCK_WRITE_PROCESS)
				{
					result = SQLiteHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters2) == 1;
				}
				break;
			}
			case 2:
			{
				MySqlParameter[] commandParameters = new MySqlParameter[1]
				{
					new MySqlParameter("@Id", MySqlDbType.Int64)
					{
						Value = logId
					}
				};
				result = MySQLHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, text, commandParameters) == 1;
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
		return result;
	}

	/// <summary>
	/// 收缩日志DB
	/// </summary>
	/// <returns></returns>
	internal static void ShrinkLogDB(DateTime time)
	{
		try
		{
			switch (LogSourceType)
			{
			case 1:
			{
				string commandText = " delete from process where create_time<=@Time;\r\n                                            delete from process_detail where create_time<=@Time;";
				SQLiteParameter[] commandParameters2 = new SQLiteParameter[1]
				{
					new SQLiteParameter("@Time", DbType.DateTime)
					{
						Value = time
					}
				};
				lock (LOCK_WRITE_PROCESS)
				{
					SQLiteHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, commandText, commandParameters2);
					break;
				}
			}
			case 2:
			{
				string cmdText = " delete from process where create_time<=@Time;\r\n                                            delete from process_detail where create_time<=@Time;";
				MySqlParameter[] commandParameters = new MySqlParameter[1]
				{
					new MySqlParameter("@Time", MySqlDbType.DateTime)
					{
						Value = time
					}
				};
				MySQLHelper.ExecuteNonQuery(LOG_CONNSTR, CommandType.Text, cmdText, commandParameters);
				break;
			}
			default:
				throw new Exception("未知的日志源类型");
			}
		}
		catch (Exception ex)
		{
			LocalLog.Error(ex.Message);
		}
	}
}
